summaryrefslogtreecommitdiffstats
path: root/src/ClientHandle.cpp
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2021-11-11 22:02:29 +0100
committerGitHub <noreply@github.com>2021-11-11 22:02:29 +0100
commitd49ce751ba6f8f2eb171633cea30a1119935f8c7 (patch)
tree25cb23102c0d778cada555c0c25e6dc3247a6514 /src/ClientHandle.cpp
parentPrevent placing of hangables on illegal blocks and break when support block broken (#5301) (diff)
downloadcuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.tar
cuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.tar.gz
cuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.tar.bz2
cuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.tar.lz
cuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.tar.xz
cuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.tar.zst
cuberite-d49ce751ba6f8f2eb171633cea30a1119935f8c7.zip
Diffstat (limited to 'src/ClientHandle.cpp')
-rw-r--r--src/ClientHandle.cpp108
1 files changed, 53 insertions, 55 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 4745ff7cd..a42212002 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -76,6 +76,7 @@ cClientHandle::cClientHandle(const AString & a_IPString, int a_ViewDistance) :
m_LastStreamedChunkX(std::numeric_limits<decltype(m_LastStreamedChunkX)>::max()), // bogus chunk coords to force streaming upon login
m_LastStreamedChunkZ(std::numeric_limits<decltype(m_LastStreamedChunkZ)>::max()),
m_TicksSinceLastPacket(0),
+ m_TimeSinceLastUnloadCheck(0),
m_Ping(1000),
m_PingID(1),
m_BlockDigAnimStage(-1),
@@ -243,6 +244,36 @@ void cClientHandle::ProxyInit(const AString & a_IPString, const cUUID & a_UUID,
+void cClientHandle::ProcessProtocolIn(void)
+{
+ // Process received network data:
+ decltype(m_IncomingData) IncomingData;
+ {
+ cCSLock Lock(m_CSIncomingData);
+
+ // Bail out when nothing was received:
+ if (m_IncomingData.empty())
+ {
+ return;
+ }
+
+ std::swap(IncomingData, m_IncomingData);
+ }
+
+ try
+ {
+ m_Protocol.HandleIncomingData(*this, IncomingData);
+ }
+ catch (const std::exception & Oops)
+ {
+ Kick(Oops.what());
+ }
+}
+
+
+
+
+
void cClientHandle::ProcessProtocolOut()
{
decltype(m_OutgoingData) OutgoingData;
@@ -394,7 +425,7 @@ void cClientHandle::FinishAuthenticate()
}
catch (const std::exception & Oops)
{
- LOGWARNING("Error reading player \"%s\": %s", GetUsername().c_str(), Oops.what());
+ LOGWARNING("Player \"%s\" save or statistics file loading failed: %s", GetUsername().c_str(), Oops.what());
Kick("Contact an operator.\n\nYour player's save files could not be parsed.\nTo avoid data loss you are prevented from joining.");
return;
}
@@ -632,8 +663,6 @@ void cClientHandle::UnloadOutOfRangeChunks(void)
m_Player->GetWorld()->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this);
SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ);
}
-
- m_LastUnloadCheck = m_Player->GetWorld()->GetWorldAge();
}
@@ -815,8 +844,8 @@ void cClientHandle::HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
// Only allow enchantment if the player has sufficient levels and lapis to enchant:
if ((m_Player->GetCurrentXp() >= XpRequired) && (LapisStack.m_ItemCount >= LapisRequired))
{
- /** We need to reduce the player's level by the number of lapis required.
- However we need to keep the resulting percentage filled the same. */
+ // We need to reduce the player's level by the number of lapis required.
+ // However we need to keep the resulting percentage filled the same.
const auto TargetLevel = m_Player->GetXpLevel() - LapisRequired;
const auto CurrentFillPercent = m_Player->GetXpPercentage();
@@ -842,7 +871,7 @@ void cClientHandle::HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
}
}
- // Retrieve the enchanted item corresponding to our chosen option (top, middle, bottom)
+ // The enchanted item corresponding to our chosen option (top, middle, bottom).
cItem EnchantedItem = Window->m_SlotArea->SelectEnchantedOption(a_Enchantment);
// Set the item slot to our new enchanted item:
@@ -2071,19 +2100,10 @@ bool cClientHandle::CheckBlockInteractionsRate(void)
-void cClientHandle::Tick(float a_Dt)
+void cClientHandle::Tick(std::chrono::milliseconds a_Dt)
{
using namespace std::chrono_literals;
- // anticheat fastbreak
- if (m_HasStartedDigging)
- {
- BLOCKTYPE Block = m_Player->GetWorld()->GetBlock({ m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ });
- m_BreakProgress += m_Player->GetMiningProgressPerTick(Block);
- }
-
- ProcessProtocolIn();
-
if (IsDestroyed())
{
return;
@@ -2156,16 +2176,24 @@ void cClientHandle::Tick(float a_Dt)
StreamNextChunks();
// Unload all chunks that are out of the view distance (every 5 seconds):
- if ((m_Player->GetWorld()->GetWorldAge() - m_LastUnloadCheck) > 5s)
+ if ((m_TimeSinceLastUnloadCheck += a_Dt) > 5s)
{
UnloadOutOfRangeChunks();
+ m_TimeSinceLastUnloadCheck = 0s;
+ }
+
+ // anticheat fastbreak
+ if (m_HasStartedDigging)
+ {
+ BLOCKTYPE Block = m_Player->GetWorld()->GetBlock({ m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ });
+ m_BreakProgress += m_Player->GetMiningProgressPerTick(Block);
}
// Handle block break animation:
if (m_BlockDigAnimStage > -1)
{
int lastAnimVal = m_BlockDigAnimStage;
- m_BlockDigAnimStage += static_cast<int>(m_BlockDigAnimSpeed * a_Dt);
+ m_BlockDigAnimStage += static_cast<int>(m_BlockDigAnimSpeed * a_Dt.count());
if (m_BlockDigAnimStage > 9000)
{
m_BlockDigAnimStage = 9000;
@@ -2903,17 +2931,17 @@ void cClientHandle::SendResetTitle()
-void cClientHandle::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
+void cClientHandle::SendRespawn(const eDimension a_Dimension, const bool a_IsRespawningFromDeath)
{
- if (!a_ShouldIgnoreDimensionChecks && (a_Dimension == m_Player->GetWorld()->GetDimension()))
+ if (!a_IsRespawningFromDeath && (a_Dimension == m_Player->GetWorld()->GetDimension()))
{
// The client goes crazy if we send a respawn packet with the dimension of the current world
// So we send a temporary one first.
- // This is not needed when the player dies, hence the a_ShouldIgnoreDimensionChecks flag.
- // a_ShouldIgnoreDimensionChecks is true only at cPlayer::Respawn, which is called after
- // the player dies.
- eDimension TemporaryDimension = (a_Dimension == dimOverworld) ? dimNether : dimOverworld;
- m_Protocol->SendRespawn(TemporaryDimension);
+ // This is not needed when the player dies, hence the a_IsRespawningFromDeath flag.
+ // a_IsRespawningFromDeath is true only at cPlayer::Respawn, which is called after the player dies.
+
+ // First send a temporary dimension to placate the client:
+ m_Protocol->SendRespawn((a_Dimension == dimOverworld) ? dimNether : dimOverworld);
}
m_Protocol->SendRespawn(a_Dimension);
@@ -3383,36 +3411,6 @@ bool cClientHandle::SetState(eState a_NewState)
-void cClientHandle::ProcessProtocolIn(void)
-{
- // Process received network data:
- decltype(m_IncomingData) IncomingData;
- {
- cCSLock Lock(m_CSIncomingData);
-
- // Bail out when nothing was received:
- if (m_IncomingData.empty())
- {
- return;
- }
-
- std::swap(IncomingData, m_IncomingData);
- }
-
- try
- {
- m_Protocol.HandleIncomingData(*this, IncomingData);
- }
- catch (const std::exception & Oops)
- {
- Kick(Oops.what());
- }
-}
-
-
-
-
-
void cClientHandle::OnLinkCreated(cTCPLinkPtr a_Link)
{
m_Link = a_Link;