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

View File

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