1
0

Merge branch 'master' into c++11Events

This commit is contained in:
Mattes D 2014-10-24 10:13:54 +02:00
commit 2940ced832
45 changed files with 305 additions and 190 deletions

View File

@ -81,7 +81,6 @@ set(SQLITECPP_BUILD_TESTS OFF CACHE BOOL "Build and run tests."
set(SQLITECPP_INTERNAL_SQLITE OFF CACHE BOOL "Add the internal SQLite3 source to the project." FORCE) set(SQLITECPP_INTERNAL_SQLITE OFF CACHE BOOL "Add the internal SQLite3 source to the project." FORCE)
# Include all the libraries: # Include all the libraries:
add_subdirectory(lib/inifile/)
add_subdirectory(lib/jsoncpp/) add_subdirectory(lib/jsoncpp/)
add_subdirectory(lib/zlib/) add_subdirectory(lib/zlib/)
add_subdirectory(lib/lua/) add_subdirectory(lib/lua/)

View File

@ -4,7 +4,7 @@
#include "src/Generating/BioGen.h" #include "src/Generating/BioGen.h"
#include "src/StringCompression.h" #include "src/StringCompression.h"
#include "src/WorldStorage/FastNBT.h" #include "src/WorldStorage/FastNBT.h"
#include "inifile/iniFile.h" #include "src/IniFile.h"

View File

@ -3,7 +3,7 @@
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include "src/Generating/BioGen.h" #include "src/Generating/BioGen.h"
#include "inifile/iniFile.h" #include "src/IniFile.h"

View File

@ -8,7 +8,7 @@
#include <QSettings> #include <QSettings>
#include <QDirIterator> #include <QDirIterator>
#include <QStatusBar> #include <QStatusBar>
#include "inifile/iniFile.h" #include "src/IniFile.h"
#include "ChunkSource.h" #include "ChunkSource.h"
#include "src/Generating/BioGen.h" #include "src/Generating/BioGen.h"
#include "src/StringCompression.h" #include "src/StringCompression.h"

View File

@ -21,7 +21,7 @@ SOURCES +=\
../../src/StringUtils.cpp \ ../../src/StringUtils.cpp \
../../src/LoggerListeners.cpp \ ../../src/LoggerListeners.cpp \
../../src/Logger.cpp \ ../../src/Logger.cpp \
../../lib/inifile/iniFile.cpp \ ../../src/IniFile.cpp \
../../src/OSSupport/File.cpp \ ../../src/OSSupport/File.cpp \
../../src/OSSupport/CriticalSection.cpp \ ../../src/OSSupport/CriticalSection.cpp \
../../src/OSSupport/IsThread.cpp \ ../../src/OSSupport/IsThread.cpp \
@ -59,7 +59,7 @@ HEADERS += MainWindow.h \
../../src/StringUtils.h \ ../../src/StringUtils.h \
../../src/LoggerListeners.h \ ../../src/LoggerListeners.h \
../../src/Logger.h \ ../../src/Logger.h \
../../lib/inifile/iniFile.h \ ../../src/IniFile.h \
../../src/OSSupport/File.h \ ../../src/OSSupport/File.h \
../../src/OSSupport/CriticalSection.h \ ../../src/OSSupport/CriticalSection.h \
../../src/OSSupport/IsThread.h \ ../../src/OSSupport/IsThread.h \

View File

@ -1,11 +0,0 @@
cmake_minimum_required (VERSION 2.6)
project (iniFile)
include_directories ("${PROJECT_SOURCE_DIR}/../../src/")
file(GLOB SOURCE
"*.h"
"*.cpp"
)
add_library(iniFile ${SOURCE})

View File

@ -15,7 +15,7 @@ $cfile "../Vector3.h"
$cfile "../ChunkDef.h" $cfile "../ChunkDef.h"
$cfile "../BiomeDef.h" $cfile "../BiomeDef.h"
$cfile "../../lib/inifile/iniFile.h" $cfile "../IniFile.h"
$cfile "../OSSupport/File.h" $cfile "../OSSupport/File.h"

View File

@ -9,7 +9,7 @@
#include "../Server.h" #include "../Server.h"
#include "../CommandOutput.h" #include "../CommandOutput.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "../Entities/Player.h" #include "../Entities/Player.h"
#define FIND_HOOK(a_HookName) HookMap::iterator Plugins = m_Hooks.find(a_HookName); #define FIND_HOOK(a_HookName) HookMap::iterator Plugins = m_Hooks.find(a_HookName);

View File

@ -4,7 +4,7 @@
#include "Globals.h" #include "Globals.h"
#include "BlockID.h" #include "BlockID.h"
#include "inifile/iniFile.h" #include "IniFile.h"
#include "Item.h" #include "Item.h"
#include "Mobs/Monster.h" #include "Mobs/Monster.h"

View File

@ -34,6 +34,7 @@ SET (SRCS
FastRandom.cpp FastRandom.cpp
FurnaceRecipe.cpp FurnaceRecipe.cpp
Globals.cpp Globals.cpp
IniFile.cpp
Inventory.cpp Inventory.cpp
Item.cpp Item.cpp
ItemGrid.cpp ItemGrid.cpp
@ -98,6 +99,7 @@ SET (HDRS
ForEachChunkProvider.h ForEachChunkProvider.h
FurnaceRecipe.h FurnaceRecipe.h
Globals.h Globals.h
IniFile.h
Inventory.h Inventory.h
Item.h Item.h
ItemGrid.h ItemGrid.h
@ -320,4 +322,4 @@ endif ()
if (WIN32) if (WIN32)
target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib) target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib)
endif() endif()
target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib sqlite lua SQLiteCpp) target_link_libraries(${EXECUTABLE} luaexpat jsoncpp polarssl zlib sqlite lua SQLiteCpp)

View File

@ -1742,7 +1742,7 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max
// Re-send the chunk to all clients: // Re-send the chunk to all clients:
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
m_World->ForceSendChunkTo(m_PosX, m_PosZ, (*itr)); m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, (*itr));
} // for itr - m_LoadedByClient[] } // for itr - m_LoadedByClient[]
} }

View File

@ -91,17 +91,45 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkZ)
void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client)
{ {
ASSERT(a_Client != nullptr); ASSERT(a_Client != nullptr);
{ {
sSendChunk Chunk(a_ChunkX, a_ChunkZ, a_Client);
cCSLock Lock(m_CS); cCSLock Lock(m_CS);
if (std::find(m_SendChunks.begin(), m_SendChunks.end(), sSendChunk(a_ChunkX, a_ChunkZ, a_Client)) != m_SendChunks.end()) if (
std::find(m_SendChunksLowPriority.begin(), m_SendChunksLowPriority.end(), Chunk) != m_SendChunksLowPriority.end() ||
std::find(m_SendChunksMediumPriority.begin(), m_SendChunksMediumPriority.end(), Chunk) != m_SendChunksMediumPriority.end() ||
std::find(m_SendChunksHighPriority.begin(), m_SendChunksHighPriority.end(), Chunk) != m_SendChunksHighPriority.end()
)
{ {
// Already queued, bail out // Already queued, bail out
return; return;
} }
m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkZ, a_Client));
switch (a_Priority)
{
case E_CHUNK_PRIORITY_LOW:
{
m_SendChunksLowPriority.push_back(Chunk);
break;
}
case E_CHUNK_PRIORITY_MEDIUM:
{
m_SendChunksMediumPriority.push_back(Chunk);
break;
}
case E_CHUNK_PRIORITY_HIGH:
{
m_SendChunksHighPriority.push_back(Chunk);
break;
}
default:
{
ASSERT(!"Unknown chunk priority!");
}
}
} }
m_evtQueue.Set(); m_evtQueue.Set();
} }
@ -114,15 +142,33 @@ void cChunkSender::RemoveClient(cClientHandle * a_Client)
{ {
{ {
cCSLock Lock(m_CS); cCSLock Lock(m_CS);
for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();) for (sSendChunkList::iterator itr = m_SendChunksLowPriority.begin(); itr != m_SendChunksLowPriority.end();)
{ {
if (itr->m_Client == a_Client) if (itr->m_Client == a_Client)
{ {
itr = m_SendChunks.erase(itr); itr = m_SendChunksLowPriority.erase(itr);
continue; continue;
} }
++itr; ++itr;
} // for itr - m_SendChunks[] } // for itr - m_SendChunksLowPriority[]
for (sSendChunkList::iterator itr = m_SendChunksMediumPriority.begin(); itr != m_SendChunksMediumPriority.end();)
{
if (itr->m_Client == a_Client)
{
itr = m_SendChunksMediumPriority.erase(itr);
continue;
}
++itr;
} // for itr - m_SendChunksMediumPriority[]
for (sSendChunkList::iterator itr = m_SendChunksHighPriority.begin(); itr != m_SendChunksHighPriority.end();)
{
if (itr->m_Client == a_Client)
{
itr = m_SendChunksHighPriority.erase(itr);
continue;
}
++itr;
} // for itr - m_SendChunksHighPriority[]
m_RemoveCount++; m_RemoveCount++;
} }
m_evtQueue.Set(); m_evtQueue.Set();
@ -138,7 +184,7 @@ void cChunkSender::Execute(void)
while (!m_ShouldTerminate) while (!m_ShouldTerminate)
{ {
cCSLock Lock(m_CS); cCSLock Lock(m_CS);
while (m_ChunksReady.empty() && m_SendChunks.empty()) while (m_ChunksReady.empty() && m_SendChunksLowPriority.empty() && m_SendChunksHighPriority.empty())
{ {
int RemoveCount = m_RemoveCount; int RemoveCount = m_RemoveCount;
m_RemoveCount = 0; m_RemoveCount = 0;
@ -154,7 +200,16 @@ void cChunkSender::Execute(void)
} }
} // while (empty) } // while (empty)
if (!m_ChunksReady.empty()) if (!m_SendChunksHighPriority.empty())
{
// Take one from the queue:
sSendChunk Chunk(m_SendChunksHighPriority.front());
m_SendChunksHighPriority.pop_front();
Lock.Unlock();
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
}
else if (!m_ChunksReady.empty())
{ {
// Take one from the queue: // Take one from the queue:
cChunkCoords Coords(m_ChunksReady.front()); cChunkCoords Coords(m_ChunksReady.front());
@ -163,11 +218,20 @@ void cChunkSender::Execute(void)
SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, nullptr); SendChunk(Coords.m_ChunkX, Coords.m_ChunkZ, nullptr);
} }
else if (!m_SendChunksMediumPriority.empty())
{
// Take one from the queue:
sSendChunk Chunk(m_SendChunksMediumPriority.front());
m_SendChunksMediumPriority.pop_front();
Lock.Unlock();
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
}
else else
{ {
// Take one from the queue: // Take one from the queue:
sSendChunk Chunk(m_SendChunks.front()); sSendChunk Chunk(m_SendChunksLowPriority.front());
m_SendChunks.pop_front(); m_SendChunksLowPriority.pop_front();
Lock.Unlock(); Lock.Unlock();
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client); SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkZ, Chunk.m_Client);
@ -192,12 +256,9 @@ void cChunkSender::SendChunk(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Clien
ASSERT(m_World != nullptr); ASSERT(m_World != nullptr);
// Ask the client if it still wants the chunk: // Ask the client if it still wants the chunk:
if (a_Client != nullptr) if ((a_Client != nullptr) && !a_Client->WantsSendChunk(a_ChunkX, a_ChunkZ))
{ {
if (!a_Client->WantsSendChunk(a_ChunkX, a_ChunkZ)) return;
{
return;
}
} }
// If the chunk has no clients, no need to packetize it: // If the chunk has no clients, no need to packetize it:

View File

@ -76,6 +76,13 @@ public:
cChunkSender(void); cChunkSender(void);
~cChunkSender(); ~cChunkSender();
enum eChunkPriority
{
E_CHUNK_PRIORITY_HIGH = 0,
E_CHUNK_PRIORITY_MEDIUM = 1,
E_CHUNK_PRIORITY_LOW = 2,
};
bool Start(cWorld * a_World); bool Start(cWorld * a_World);
void Stop(void); void Stop(void);
@ -84,7 +91,7 @@ public:
void ChunkReady(int a_ChunkX, int a_ChunkZ); void ChunkReady(int a_ChunkX, int a_ChunkZ);
/// Queues a chunk to be sent to a specific client /// Queues a chunk to be sent to a specific client
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client);
/// Removes the a_Client from all waiting chunk send operations /// Removes the a_Client from all waiting chunk send operations
void RemoveClient(cClientHandle * a_Client); void RemoveClient(cClientHandle * a_Client);
@ -136,7 +143,9 @@ protected:
cCriticalSection m_CS; cCriticalSection m_CS;
cChunkCoordsList m_ChunksReady; cChunkCoordsList m_ChunksReady;
sSendChunkList m_SendChunks; sSendChunkList m_SendChunksLowPriority;
sSendChunkList m_SendChunksMediumPriority;
sSendChunkList m_SendChunksHighPriority;
cEvent m_evtQueue; // Set when anything is added to m_ChunksReady cEvent m_evtQueue; // Set when anything is added to m_ChunksReady
cEvent m_evtRemoved; // Set when removed clients are safe to be deleted cEvent m_evtRemoved; // Set when removed clients are safe to be deleted
int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times) int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times)

View File

@ -405,53 +405,145 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
void cClientHandle::StreamChunks(void) bool cClientHandle::StreamNextChunk(void)
{ {
if ((m_State < csAuthenticated) || (m_State >= csDestroying)) if ((m_State < csAuthenticated) || (m_State >= csDestroying))
{ {
return; return true;
} }
ASSERT(m_Player != nullptr); ASSERT(m_Player != nullptr);
int ChunkPosX = FAST_FLOOR_DIV((int)m_Player->GetPosX(), cChunkDef::Width); int ChunkPosX = m_Player->GetChunkX();
int ChunkPosZ = FAST_FLOOR_DIV((int)m_Player->GetPosZ(), cChunkDef::Width); int ChunkPosZ = m_Player->GetChunkZ();
if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ)) if ((m_LastStreamedChunkX == ChunkPosX) && (m_LastStreamedChunkZ == ChunkPosZ))
{ {
// Already streamed for this position // All chunks are already loaded. Abort loading.
return; return true;
} }
// Get the look vector and normalize it.
Vector3d Position = m_Player->GetEyePosition();
Vector3d LookVector = m_Player->GetLookVector();
LookVector.Normalize();
// Lock the list
cCSLock Lock(m_CSChunkLists);
// High priority: Load the chunks that are in the view-direction of the player (with a radius of 3)
for (int Range = 0; Range < m_ViewDistance; Range++)
{
Vector3d Vector = Position + LookVector * cChunkDef::Width * Range;
// Get the chunk from the x/z coords.
int RangeX, RangeZ = 0;
cChunkDef::BlockToChunk(FloorC(Vector.x), FloorC(Vector.z), RangeX, RangeZ);
for (size_t X = 0; X < 7; X++)
{
for (size_t Z = 0; Z < 7; Z++)
{
int ChunkX = RangeX + ((X >= 4) ? (3 - X) : X);
int ChunkZ = RangeZ + ((Z >= 4) ? (3 - Z) : Z);
cChunkCoords Coords(ChunkX, ChunkZ);
// Checks if the chunk is in distance
if ((Diff(ChunkX, ChunkPosX) > m_ViewDistance) || (Diff(ChunkZ, ChunkPosZ) > m_ViewDistance))
{
continue;
}
// If the chunk already loading/loaded -> skip
if (
(std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), Coords) != m_ChunksToSend.end()) ||
(std::find(m_LoadedChunks.begin(), m_LoadedChunks.end(), Coords) != m_LoadedChunks.end())
)
{
continue;
}
// Unloaded chunk found -> Send it to the client.
Lock.Unlock();
StreamChunk(ChunkX, ChunkZ, ((Range <= 2) ? cChunkSender::E_CHUNK_PRIORITY_HIGH : cChunkSender::E_CHUNK_PRIORITY_MEDIUM));
return false;
}
}
}
// Low priority: Add all chunks that are in range. (From the center out to the edge)
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:
cChunkCoordsList CurcleChunks;
for (int i = -d; i <= d; ++i)
{
CurcleChunks.push_back(cChunkCoords(ChunkPosX + d, ChunkPosZ + i));
CurcleChunks.push_back(cChunkCoords(ChunkPosX - d, ChunkPosZ + i));
}
for (int i = -d + 1; i < d; ++i)
{
CurcleChunks.push_back(cChunkCoords(ChunkPosX + i, ChunkPosZ + d));
CurcleChunks.push_back(cChunkCoords(ChunkPosX + i, ChunkPosZ - d));
}
// For each the CurcleChunks list and send the first unloaded chunk:
for (cChunkCoordsList::iterator itr = CurcleChunks.begin(), end = CurcleChunks.end(); itr != end; ++itr)
{
cChunkCoords Coords = *itr;
// If the chunk already loading/loaded -> skip
if (
(std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), Coords) != m_ChunksToSend.end()) ||
(std::find(m_LoadedChunks.begin(), m_LoadedChunks.end(), Coords) != m_LoadedChunks.end())
)
{
continue;
}
// Unloaded chunk found -> Send it to the client.
Lock.Unlock();
StreamChunk(Coords.m_ChunkX, Coords.m_ChunkZ, cChunkSender::E_CHUNK_PRIORITY_LOW);
return false;
}
}
// All chunks are loaded -> Sets the last loaded chunk coordinates to current coordinates
m_LastStreamedChunkX = ChunkPosX; m_LastStreamedChunkX = ChunkPosX;
m_LastStreamedChunkZ = ChunkPosZ; m_LastStreamedChunkZ = ChunkPosZ;
return true;
}
LOGD("Streaming chunks centered on [%d, %d], view distance %d", ChunkPosX, ChunkPosZ, m_ViewDistance);
cWorld * World = m_Player->GetWorld();
ASSERT(World != nullptr);
// Remove all loaded chunks that are no longer in range; deferred to out-of-CS:
cChunkCoordsList RemoveChunks;
void cClientHandle::UnloadOutOfRangeChunks(void)
{
int ChunkPosX = FAST_FLOOR_DIV((int)m_Player->GetPosX(), cChunkDef::Width);
int ChunkPosZ = FAST_FLOOR_DIV((int)m_Player->GetPosZ(), cChunkDef::Width);
cChunkCoordsList ChunksToRemove;
{ {
cCSLock Lock(m_CSChunkLists); cCSLock Lock(m_CSChunkLists);
for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end();) for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end();)
{ {
int RelX = (*itr).m_ChunkX - ChunkPosX; int DiffX = Diff((*itr).m_ChunkX, ChunkPosX);
int RelZ = (*itr).m_ChunkZ - ChunkPosZ; int DiffZ = Diff((*itr).m_ChunkZ, ChunkPosZ);
if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) if ((DiffX > m_ViewDistance) || (DiffZ > m_ViewDistance))
{ {
RemoveChunks.push_back(*itr); ChunksToRemove.push_back(*itr);
itr = m_LoadedChunks.erase(itr); itr = m_LoadedChunks.erase(itr);
} }
else else
{ {
++itr; ++itr;
} }
} // for itr - m_LoadedChunks[] }
for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();) for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();)
{ {
int RelX = (*itr).m_ChunkX - ChunkPosX; int DiffX = Diff((*itr).m_ChunkX, ChunkPosX);
int RelZ = (*itr).m_ChunkZ - ChunkPosZ; int DiffZ = Diff((*itr).m_ChunkZ, ChunkPosZ);
if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) if ((DiffX > m_ViewDistance) || (DiffZ > m_ViewDistance))
{ {
itr = m_ChunksToSend.erase(itr); itr = m_ChunksToSend.erase(itr);
} }
@ -459,52 +551,21 @@ void cClientHandle::StreamChunks(void)
{ {
++itr; ++itr;
} }
} // for itr - m_ChunksToSend[] }
} }
for (cChunkCoordsList::iterator itr = RemoveChunks.begin(); itr != RemoveChunks.end(); ++itr)
for (cChunkCoordsList::iterator itr = ChunksToRemove.begin(); itr != ChunksToRemove.end(); ++itr)
{ {
World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this); m_Player->GetWorld()->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this);
m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ); m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ);
} // for itr - RemoveChunks[] }
// 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 <= 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)
{
StreamChunk(ChunkPosX + d, ChunkPosZ + i);
StreamChunk(ChunkPosX - d, ChunkPosZ + i);
} // for i
for (int i = -d + 1; i < d; ++i)
{
StreamChunk(ChunkPosX + i, ChunkPosZ + d);
StreamChunk(ChunkPosX + i, ChunkPosZ - d);
} // for i
} // for d
// Touch chunks GENERATEDISTANCE ahead to let them generate:
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)
{
World->TouchChunk(ChunkPosX + d, ChunkPosZ + i);
World->TouchChunk(ChunkPosX - d, ChunkPosZ + i);
} // for i
for (int i = -d + 1; i < d; ++i)
{
World->TouchChunk(ChunkPosX + i, ChunkPosZ + d);
World->TouchChunk(ChunkPosX + i, ChunkPosZ - d);
} // for i
} // for d
} }
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority)
{ {
if (m_State >= csDestroying) if (m_State >= csDestroying)
{ {
@ -522,7 +583,7 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
} }
World->SendChunkTo(a_ChunkX, a_ChunkZ, this); World->SendChunkTo(a_ChunkX, a_ChunkZ, a_Priority, this);
} }
} }
@ -1875,6 +1936,7 @@ void cClientHandle::RemoveFromWorld(void)
// Here, we set last streamed values to bogus ones so everything is resent // Here, we set last streamed values to bogus ones so everything is resent
m_LastStreamedChunkX = 0x7fffffff; m_LastStreamedChunkX = 0x7fffffff;
m_LastStreamedChunkZ = 0x7fffffff; m_LastStreamedChunkZ = 0x7fffffff;
m_HasSentPlayerChunk = false; m_HasSentPlayerChunk = false;
} }
@ -1941,6 +2003,26 @@ void cClientHandle::Tick(float a_Dt)
} }
} }
if ((m_State >= csAuthenticated) && (m_State < csDestroying))
{
// Stream 4 chunks per tick
for (int i = 0; i < 4; i++)
{
// Stream the next chunk
if (StreamNextChunk())
{
// Streaming finished. All chunks are loaded.
break;
}
}
// Unload all chunks that are out of the view distance (all 5 seconds)
if ((m_Player->GetWorld()->GetWorldAge() % 100) == 0)
{
UnloadOutOfRangeChunks();
}
}
// Handle block break animation: // Handle block break animation:
if (m_BlockDigAnimStage > -1) if (m_BlockDigAnimStage > -1)
{ {
@ -1977,7 +2059,7 @@ void cClientHandle::ServerTick(float a_Dt)
if (m_State == csAuthenticated) if (m_State == csAuthenticated)
{ {
StreamChunks(); StreamNextChunk();
// Remove the client handle from the server, it will be ticked from its cPlayer object from now on // Remove the client handle from the server, it will be ticked from its cPlayer object from now on
cRoot::Get()->GetServer()->ClientMovedToWorld(this); cRoot::Get()->GetServer()->ClientMovedToWorld(this);
@ -2765,18 +2847,8 @@ void cClientHandle::SetUsername( const AString & a_Username)
void cClientHandle::SetViewDistance(int a_ViewDistance) void cClientHandle::SetViewDistance(int a_ViewDistance)
{ {
if (a_ViewDistance < MIN_VIEW_DISTANCE) m_ViewDistance = Clamp(a_ViewDistance, MIN_VIEW_DISTANCE, MAX_VIEW_DISTANCE);
{ LOGD("Setted %s's view distance to %i", GetUsername().c_str(), m_ViewDistance);
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();
} }

View File

@ -21,6 +21,7 @@
#include "Enchantments.h" #include "Enchantments.h"
#include "UI/SlotArea.h" #include "UI/SlotArea.h"
#include "json/json.h" #include "json/json.h"
#include "ChunkSender.h"
@ -113,7 +114,11 @@ public:
/** Authenticates the specified user, called by cAuthenticator */ /** Authenticates the specified user, called by cAuthenticator */
void Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties); void Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);
void StreamChunks(void); /** This function sends a new unloaded chunk to the player. Returns true if all chunks are loaded. */
bool StreamNextChunk();
/** Remove all loaded chunks that are no longer in range */
void UnloadOutOfRangeChunks(void);
// Removes the client from all chunks. Used when switching worlds or destroying the player // Removes the client from all chunks. Used when switching worlds or destroying the player
void RemoveFromAllChunks(void); void RemoveFromAllChunks(void);
@ -445,7 +450,7 @@ private:
bool CheckBlockInteractionsRate(void); bool CheckBlockInteractionsRate(void);
/** Adds a single chunk to be streamed to the client; used by StreamChunks() */ /** Adds a single chunk to be streamed to the client; used by StreamChunks() */
void StreamChunk(int a_ChunkX, int a_ChunkZ); void StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority);
/** Handles the DIG_STARTED dig packet: */ /** Handles the DIG_STARTED dig packet: */
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);

View File

@ -20,7 +20,7 @@
#include "../WorldStorage/StatSerializer.h" #include "../WorldStorage/StatSerializer.h"
#include "../CompositeChat.h" #include "../CompositeChat.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "json/json.h" #include "json/json.h"
// 6000 ticks or 5 minutes // 6000 ticks or 5 minutes
@ -235,7 +235,6 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
CanMove = false; CanMove = false;
TeleportToCoords(m_LastPos.x, m_LastPos.y, m_LastPos.z); TeleportToCoords(m_LastPos.x, m_LastPos.y, m_LastPos.z);
} }
m_ClientHandle->StreamChunks();
} }
if (CanMove) if (CanMove)

View File

@ -5,7 +5,7 @@
#include "Globals.h" #include "Globals.h"
#include "BioGen.h" #include "BioGen.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "../LinearUpscale.h" #include "../LinearUpscale.h"

View File

@ -65,5 +65,5 @@ SET (HDRS
if(NOT MSVC) if(NOT MSVC)
add_library(Generating ${SRCS} ${HDRS}) add_library(Generating ${SRCS} ${HDRS})
target_link_libraries(Generating OSSupport iniFile Blocks) target_link_libraries(Generating OSSupport Blocks)
endif() endif()

View File

@ -2,7 +2,7 @@
#include "Globals.h" #include "Globals.h"
#include "ChunkGenerator.h" #include "ChunkGenerator.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "ChunkDesc.h" #include "ChunkDesc.h"
#include "ComposableGenerator.h" #include "ComposableGenerator.h"
#include "Noise3DGenerator.h" #include "Noise3DGenerator.h"

View File

@ -12,7 +12,7 @@
#include "../BlockID.h" #include "../BlockID.h"
#include "../Item.h" #include "../Item.h"
#include "../LinearUpscale.h" #include "../LinearUpscale.h"
#include "inifile/iniFile.h" #include "../IniFile.h"

View File

@ -7,7 +7,7 @@
#include "ComposableGenerator.h" #include "ComposableGenerator.h"
#include "../World.h" #include "../World.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "../Root.h" #include "../Root.h"
// Individual composed algorithms: // Individual composed algorithms:

View File

@ -7,7 +7,7 @@
#include "DistortedHeightmap.h" #include "DistortedHeightmap.h"
#include "../OSSupport/File.h" #include "../OSSupport/File.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "../LinearUpscale.h" #include "../LinearUpscale.h"

View File

@ -5,7 +5,7 @@
#include "Globals.h" #include "Globals.h"
#include "EndGen.h" #include "EndGen.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "../LinearUpscale.h" #include "../LinearUpscale.h"

View File

@ -15,7 +15,7 @@
#include "../Simulator/FluidSimulator.h" // for cFluidSimulator::CanWashAway() #include "../Simulator/FluidSimulator.h" // for cFluidSimulator::CanWashAway()
#include "../Simulator/FireSimulator.h" #include "../Simulator/FireSimulator.h"
#include "../World.h" #include "../World.h"
#include "inifile/iniFile.h" #include "../IniFile.h"

View File

@ -6,7 +6,7 @@
#include "Globals.h" #include "Globals.h"
#include "HeiGen.h" #include "HeiGen.h"
#include "../LinearUpscale.h" #include "../LinearUpscale.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "DistortedHeightmap.h" #include "DistortedHeightmap.h"
#include "EndGen.h" #include "EndGen.h"
#include "Noise3DGenerator.h" #include "Noise3DGenerator.h"

View File

@ -6,7 +6,7 @@
#include "Globals.h" #include "Globals.h"
#include "Noise3DGenerator.h" #include "Noise3DGenerator.h"
#include "../OSSupport/File.h" #include "../OSSupport/File.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "../LinearInterpolation.h" #include "../LinearInterpolation.h"
#include "../LinearUpscale.h" #include "../LinearUpscale.h"

View File

@ -29,5 +29,5 @@ SET (HDRS
if(NOT MSVC) if(NOT MSVC)
add_library(Generating_Prefabs ${SRCS} ${HDRS}) add_library(Generating_Prefabs ${SRCS} ${HDRS})
target_link_libraries(Generating_Prefabs OSSupport iniFile Blocks) target_link_libraries(Generating_Prefabs OSSupport Blocks)
endif() endif()

View File

@ -11,7 +11,7 @@
#include "../OSSupport/ListenThread.h" #include "../OSSupport/ListenThread.h"
#include "../OSSupport/SocketThreads.h" #include "../OSSupport/SocketThreads.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "PolarSSL++/RsaPrivateKey.h" #include "PolarSSL++/RsaPrivateKey.h"
#include "PolarSSL++/CryptoKey.h" #include "PolarSSL++/CryptoKey.h"
#include "PolarSSL++/X509Cert.h" #include "PolarSSL++/X509Cert.h"

View File

@ -24,7 +24,7 @@
#include <ctype.h> #include <ctype.h>
// Local Includes // Local Includes
#include "iniFile.h" #include "IniFile.h"
#if defined(WIN32) #if defined(WIN32)
#define iniEOL endl #define iniEOL endl
@ -32,10 +32,6 @@
#define iniEOL '\r' << endl #define iniEOL '\r' << endl
#endif #endif
#ifndef _WIN32
#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__))
#endif
using namespace std; using namespace std;
@ -465,20 +461,6 @@ bool cIniFile::SetValueF(const AString & a_KeyName, const AString & a_ValueName,
bool cIniFile::SetValueV(const AString & a_KeyName, const AString & a_ValueName, const char * a_Format, ...)
{
va_list args;
va_start(args, a_Format);
AString Data;
AppendVPrintf(Data, a_Format, args);
va_end(args);
return SetValue(a_KeyName, a_ValueName, Data);
}
AString cIniFile::GetValue(const int keyID, const int valueID, const AString & defValue) const AString cIniFile::GetValue(const int keyID, const int valueID, const AString & defValue) const
{ {
if ((keyID < (int)keys.size()) && (valueID < (int)keys[keyID].names.size())) if ((keyID < (int)keys.size()) && (valueID < (int)keys[keyID].names.size()))

View File

@ -154,12 +154,6 @@ public:
} }
bool SetValueF(const AString & a_KeyName, const AString & a_ValueName, const double a_Value, const bool a_CreateIfNotExists = true); bool SetValueF(const AString & a_KeyName, const AString & a_ValueName, const double a_Value, const bool a_CreateIfNotExists = true);
// tolua_end
bool SetValueV( const AString & a_KeyName, const AString & a_ValueName, const char * a_Format, ...);
// tolua_begin
// Deletes specified value. // Deletes specified value.
// Returns true if value existed and deleted, false otherwise. // Returns true if value existed and deleted, false otherwise.
bool DeleteValueByID(const int keyID, const int valueID); bool DeleteValueByID(const int keyID, const int valueID);

View File

@ -3,7 +3,7 @@
#include "MonsterConfig.h" #include "MonsterConfig.h"
#include "Mobs/Monster.h" #include "Mobs/Monster.h"
#include "inifile/iniFile.h" #include "IniFile.h"

View File

@ -39,6 +39,10 @@ if(NOT MSVC)
add_library(OSSupport ${SRCS} ${HDRS}) add_library(OSSupport ${SRCS} ${HDRS})
if(UNIX) if(UNIX)
target_link_libraries(OSSupport pthread rt) if(NOT APPLE)
target_link_libraries(OSSupport rt)
endif()
target_link_libraries(OSSupport pthread)
endif() endif()
endif() endif()

View File

@ -7,7 +7,7 @@
#include "../Server.h" #include "../Server.h"
#include "../ClientHandle.h" #include "../ClientHandle.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "json/json.h" #include "json/json.h"
#include "PolarSSL++/BlockingSslClientSocket.h" #include "PolarSSL++/BlockingSslClientSocket.h"

View File

@ -7,7 +7,7 @@
#include "MojangAPI.h" #include "MojangAPI.h"
#include "SQLiteCpp/Database.h" #include "SQLiteCpp/Database.h"
#include "SQLiteCpp/Statement.h" #include "SQLiteCpp/Statement.h"
#include "inifile/iniFile.h" #include "../IniFile.h"
#include "json/json.h" #include "json/json.h"
#include "PolarSSL++/BlockingSslClientSocket.h" #include "PolarSSL++/BlockingSslClientSocket.h"
#include "../RankManager.h" #include "../RankManager.h"

View File

@ -1901,6 +1901,7 @@ void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape);
m_Client->SetLocale(Locale); m_Client->SetLocale(Locale);
m_Client->SetViewDistance(ViewDistance);
// TODO: Do anything with the other values. // TODO: Do anything with the other values.
} }

View File

@ -2160,6 +2160,7 @@ void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags); HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags);
m_Client->SetLocale(Locale); m_Client->SetLocale(Locale);
m_Client->SetViewDistance(ViewDistance);
// TODO: Handle other values // TODO: Handle other values
} }

View File

@ -4,7 +4,7 @@
// Implements the cRCONServer class representing the RCON server // Implements the cRCONServer class representing the RCON server
#include "Globals.h" #include "Globals.h"
#include "inifile/iniFile.h" #include "IniFile.h"
#include "RCONServer.h" #include "RCONServer.h"
#include "Server.h" #include "Server.h"
#include "Root.h" #include "Root.h"

View File

@ -5,7 +5,7 @@
#include "Globals.h" #include "Globals.h"
#include "RankManager.h" #include "RankManager.h"
#include "inifile/iniFile.h" #include "IniFile.h"
#include "Protocol/MojangAPI.h" #include "Protocol/MojangAPI.h"
#include "ClientHandle.h" #include "ClientHandle.h"

View File

@ -19,11 +19,10 @@
#include "OSSupport/Timer.h" #include "OSSupport/Timer.h"
#include "LoggerListeners.h" #include "LoggerListeners.h"
#include "BuildInfo.h" #include "BuildInfo.h"
#include "IniFile.h"
#include "inifile/iniFile.h"
#ifdef _WIN32 #ifdef _WIN32
#include "conio.h" #include <conio.h>
#include <psapi.h> #include <psapi.h>
#elif defined(__linux__) #elif defined(__linux__)
#include <fstream> #include <fstream>

View File

@ -22,7 +22,7 @@
#include "MersenneTwister.h" #include "MersenneTwister.h"
#include "inifile/iniFile.h" #include "IniFile.h"
#include "Vector3.h" #include "Vector3.h"
#include <fstream> #include <fstream>

View File

@ -2001,7 +2001,6 @@ bool cIncrementalRedstoneSimulator<ChunkType, WorldType, GetHandlerCompileTime,
// Check if western(left) neighbor is a powered on repeater who is facing us // Check if western(left) neighbor is a powered on repeater who is facing us
if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) if (m_Chunk->UnboundedRelGetBlock(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block, OtherRepeaterDir) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{ {
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3;
if ((OtherRepeaterDir & 0x03) == 0x1) if ((OtherRepeaterDir & 0x03) == 0x1)
{ {
return true; return true;

View File

@ -7,7 +7,7 @@
#include "../Defines.h" #include "../Defines.h"
#include "../Entities/FallingBlock.h" #include "../Entities/FallingBlock.h"
#include "../Chunk.h" #include "../Chunk.h"
#include "inifile/iniFile.h" #include "../IniFile.h"

View File

@ -7,7 +7,7 @@
#include "OSSupport/Socket.h" #include "OSSupport/Socket.h"
#include "Bindings/LuaState.h" #include "Bindings/LuaState.h"
#include "inifile/iniFile.h" #include "IniFile.h"
#include "HTTPServer/HTTPServer.h" #include "HTTPServer/HTTPServer.h"
#include "HTTPServer/HTTPFormParser.h" #include "HTTPServer/HTTPFormParser.h"

View File

@ -8,7 +8,7 @@
#include "Server.h" #include "Server.h"
#include "Item.h" #include "Item.h"
#include "Root.h" #include "Root.h"
#include "inifile/iniFile.h" #include "IniFile.h"
#include "ChunkMap.h" #include "ChunkMap.h"
#include "Generating/ChunkDesc.h" #include "Generating/ChunkDesc.h"
#include "OSSupport/Timer.h" #include "OSSupport/Timer.h"
@ -2857,19 +2857,19 @@ void cWorld::RemoveClientFromChunks(cClientHandle * a_Client)
void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) void cWorld::SendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client)
{ {
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Client); m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Priority, a_Client);
} }
void cWorld::ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client) void cWorld::ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client)
{ {
a_Client->AddWantedChunk(a_ChunkX, a_ChunkZ); a_Client->AddWantedChunk(a_ChunkX, a_ChunkZ);
m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Client); m_ChunkSender.QueueSendChunkTo(a_ChunkX, a_ChunkZ, a_Priority, a_Client);
} }
@ -3498,7 +3498,6 @@ void cWorld::AddQueuedPlayers(void)
cClientHandle * Client = (*itr)->GetClientHandle(); cClientHandle * Client = (*itr)->GetClientHandle();
if (Client != nullptr) if (Client != nullptr)
{ {
Client->StreamChunks();
Client->SendPlayerMoveLook(); Client->SendPlayerMoveLook();
Client->SendHealth(); Client->SendHealth();
Client->SendWholeInventory(*(*itr)->GetWindow()); Client->SendWholeInventory(*(*itr)->GetWindow());

View File

@ -359,11 +359,11 @@ public:
/** Sends the chunk to the client specified, if the client doesn't have the chunk yet. /** Sends the chunk to the client specified, if the client doesn't have the chunk yet.
If chunk not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */ If chunk not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */
void SendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); void SendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client);
/** Sends the chunk to the client specified, even if the client already has the chunk. /** Sends the chunk to the client specified, even if the client already has the chunk.
If the chunk's not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */ If the chunk's not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */
void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client);
/** Removes client from ChunkSender's queue of chunks to be sent */ /** Removes client from ChunkSender's queue of chunks to be sent */
void RemoveClientFromChunkSender(cClientHandle * a_Client); void RemoveClientFromChunkSender(cClientHandle * a_Client);