1
0
Fork 0

Acquire chunk map CS when accessing player entities

This commit is contained in:
Peter Bell 2020-04-12 23:04:30 +01:00 committed by Mattes D
parent fb05ea7cf7
commit 43525c5df8
3 changed files with 32 additions and 29 deletions

View File

@ -435,7 +435,14 @@ bool cServer::Start(void)
bool cServer::Command(cClientHandle & a_Client, AString & a_Cmd)
{
return cRoot::Get()->GetPluginManager()->CallHookChat(*(a_Client.GetPlayer()), a_Cmd);
bool Res = cRoot::Get()->DoWithPlayerByUUID(
a_Client.GetUUID(),
[&](cPlayer & a_Player)
{
return cRoot::Get()->GetPluginManager()->CallHookChat(a_Player, a_Cmd);
}
);
return Res;
}

View File

@ -225,13 +225,15 @@ cWorld::cWorld(
cFile::CreateFolderRecursive(FILE_IO_PREFIX + m_DataPath);
m_ChunkMap = cpp14::make_unique<cChunkMap>(this);
m_ChunkMap->TrackInDeadlockDetect(a_DeadlockDetect, m_WorldName);
// Load the scoreboard
cScoreboardSerializer Serializer(m_DataPath, &m_Scoreboard);
Serializer.Load();
// Track the CSs used by this world in the deadlock detector:
a_DeadlockDetect.TrackCriticalSection(m_CSClients, Printf("World %s clients", m_WorldName.c_str()));
a_DeadlockDetect.TrackCriticalSection(m_CSPlayers, Printf("World %s players", m_WorldName.c_str()));
a_DeadlockDetect.TrackCriticalSection(m_CSTasks, Printf("World %s tasks", m_WorldName.c_str()));
// Load world settings from the ini file
@ -412,9 +414,6 @@ cWorld::cWorld(
InitializeAndLoadMobSpawningValues(IniFile);
SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", GetTimeOfDay()));
m_ChunkMap = cpp14::make_unique<cChunkMap>(this);
m_ChunkMap->TrackInDeadlockDetect(a_DeadlockDetect, m_WorldName);
// preallocate some memory for ticking blocks so we don't need to allocate that often
m_BlockTickQueue.reserve(1000);
m_BlockTickQueueCopy.reserve(1000);
@ -968,7 +967,6 @@ void cWorld::Stop(cDeadlockDetect & a_DeadlockDetect)
m_Storage.Stop();
a_DeadlockDetect.UntrackCriticalSection(m_CSClients);
a_DeadlockDetect.UntrackCriticalSection(m_CSPlayers);
a_DeadlockDetect.UntrackCriticalSection(m_CSTasks);
m_ChunkMap->UntrackInDeadlockDetect(a_DeadlockDetect);
}
@ -1405,6 +1403,7 @@ bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback
void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData)
{
cLock Lock(*this);
if (cPluginManager::Get()->CallHookExploding(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) || (a_ExplosionSize <= 0))
{
return;
@ -1420,20 +1419,17 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo
BroadcastSoundEffect("entity.generic.explode", Vector3d(a_BlockX, a_BlockY, a_BlockZ), 4.0f, SoundPitchMultiplier * 0.7f);
Vector3d ExplosionPos(a_BlockX, a_BlockY, a_BlockZ);
for (auto Player : m_Players)
{
cCSLock Lock(m_CSPlayers);
for (auto Player : m_Players)
cClientHandle * ch = Player->GetClientHandle();
if (ch == nullptr)
{
cClientHandle * ch = Player->GetClientHandle();
if (ch == nullptr)
{
continue;
}
bool InRange = (Player->GetExplosionExposureRate(ExplosionPos, static_cast<float>(a_ExplosionSize)) > 0);
auto Speed = InRange ? Player->GetSpeed() : Vector3d{};
ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, static_cast<float>(a_ExplosionSize), BlocksAffected, Speed);
continue;
}
bool InRange = (Player->GetExplosionExposureRate(ExplosionPos, static_cast<float>(a_ExplosionSize)) > 0);
auto Speed = InRange ? Player->GetSpeed() : Vector3d{};
ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, static_cast<float>(a_ExplosionSize), BlocksAffected, Speed);
}
auto Position = Vector3d(a_BlockX, a_BlockY - 0.5f, a_BlockZ);
@ -2523,7 +2519,7 @@ std::unique_ptr<cPlayer> cWorld::RemovePlayer(cPlayer & a_Player)
// Remove from the player list
{
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
LOGD("Removing player %s from world \"%s\"", a_Player.GetName().c_str(), m_WorldName.c_str());
m_Players.remove(&a_Player);
}
@ -2569,7 +2565,7 @@ bool cWorld::IsPlayerReferencedInWorldOrChunk(cPlayer & a_Player)
}
{
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
if (std::find(m_Players.begin(), m_Players.end(), &a_Player) != m_Players.end())
{
return true;
@ -2604,7 +2600,7 @@ bool cWorld::IsPlayerReferencedInWorldOrChunk(cPlayer & a_Player)
bool cWorld::ForEachPlayer(cPlayerListCallback a_Callback)
{
// Calls the callback for each player in the list
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (auto & Player : m_Players)
{
if (Player->IsTicking() && a_Callback(*Player))
@ -2622,7 +2618,7 @@ bool cWorld::ForEachPlayer(cPlayerListCallback a_Callback)
bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback a_Callback)
{
// Calls the callback for the specified player in the list
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (auto & Player : m_Players)
{
if (Player->IsTicking() && (NoCaseCompare(Player->GetName(), a_PlayerName) == 0))
@ -2644,7 +2640,7 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
size_t BestRating = 0;
size_t NameLength = a_PlayerNameHint.length();
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
if (!(*itr)->IsTicking())
@ -2676,7 +2672,7 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
bool cWorld::DoWithPlayerByUUID(const cUUID & a_PlayerUUID, cPlayerListCallback a_Callback)
{
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (auto & Player : m_Players)
{
if (Player->IsTicking() && (Player->GetUUID() == a_PlayerUUID))
@ -2696,7 +2692,7 @@ bool cWorld::DoWithNearestPlayer(Vector3d a_Pos, double a_RangeLimit, cPlayerLis
double ClosestDistance = a_RangeLimit;
cPlayer * ClosestPlayer = nullptr;
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
if (!(*itr)->IsTicking())
@ -2748,7 +2744,7 @@ bool cWorld::DoWithNearestPlayer(Vector3d a_Pos, double a_RangeLimit, cPlayerLis
void cWorld::SendPlayerList(cPlayer * a_DestPlayer)
{
// Sends the playerlist to a_DestPlayer
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
cClientHandle * ch = (*itr)->GetClientHandle();
@ -3345,7 +3341,7 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul
std::vector<pair_t> UsernamesByWeight;
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr)
{
AString PlayerName ((*itr)->GetName());
@ -3517,7 +3513,7 @@ void cWorld::AddQueuedPlayers(void)
// Add all the players in the grabbed list:
{
cCSLock Lock(m_CSPlayers);
cLock Lock(*this);
for (auto & AwaitingPlayer : PlayersToAdd)
{
auto & Player = AwaitingPlayer.first;
@ -3535,7 +3531,7 @@ void cWorld::AddQueuedPlayers(void)
PlayerPtr->SetIsTicking(true);
AddedPlayerPtrs.emplace_back(PlayerPtr, AwaitingPlayer.second);
} // for itr - PlayersToAdd[]
} // Lock(m_CSPlayers)
} // cLock(*this)
// Add all the players' clienthandles:
{

View File

@ -1205,7 +1205,7 @@ private:
std::unique_ptr<cFireSimulator> m_FireSimulator;
cRedstoneSimulator * m_RedstoneSimulator;
cCriticalSection m_CSPlayers;
// Protect with chunk map CS
cPlayerList m_Players;
cWorldStorage m_Storage;