39 #include "mbedtls/md5.h"
44 #define MAX_EXPLOSIONS_PER_TICK 20
47 #define MAX_BLOCK_CHANGE_INTERACTIONS 20
50 #define MAX_CHAT_MSG_LENGTH 1024
53 #define MAX_CHUNKS_STREAMED_PER_TICK 4
72 m_CurrentViewDistance(a_ViewDistance),
73 m_RequestedViewDistance(a_ViewDistance),
74 m_IPString(a_IPString),
76 m_CachedSentChunk(
std::numeric_limits<decltype(m_CachedSentChunk.m_ChunkX)>::max(),
std::numeric_limits<decltype(m_CachedSentChunk.m_ChunkZ)>::max()),
77 m_ProxyConnection(false),
79 m_LastStreamedChunkX(
std::numeric_limits<decltype(m_LastStreamedChunkX)>::max()),
80 m_LastStreamedChunkZ(
std::numeric_limits<decltype(m_LastStreamedChunkZ)>::max()),
81 m_TicksSinceLastPacket(0),
82 m_TimeSinceLastUnloadCheck(0),
85 m_BlockDigAnimStage(-1),
86 m_BlockDigAnimSpeed(0),
87 m_BlockDigAnimPos(s_IllegalPosition),
88 m_HasStartedDigging(false),
89 m_LastDigBlockPos(s_IllegalPosition),
91 m_NumExplosionsThisTick(0),
92 m_NumBlockChangeInteractionsThisTick(0),
94 m_HasSentPlayerChunk(false),
96 m_LastPlacedSign(s_IllegalPosition),
102 LOGD(
"New ClientHandle created at %p",
static_cast<void *
>(
this));
113 LOGD(
"Deleting client \"%s\" at %p",
GetUsername().c_str(),
static_cast<void *
>(
this));
115 LOGD(
"ClientHandle at %p deleted",
static_cast<void *
>(
this));
127 LOGD(
"%s: client %p, \"%s\" already destroyed, bailing out", __FUNCTION__,
static_cast<void *
>(
this),
m_Username.c_str());
131 LOGD(
"%s: destroying client %p, \"%s\" @ %s", __FUNCTION__,
static_cast<void *
>(
this),
m_Username.c_str(),
m_IPString.c_str());
147 bool ShouldAppendChatPrefixes,
const AString & a_ChatPrefixS,
151 if (ShouldAppendChatPrefixes)
153 return fmt::format(FMT_STRING(
"{}[{}] {}"), m_Color1, a_ChatPrefixS, m_Color2);
167 switch (a_ChatPrefix)
180 if (ShouldAppendChatPrefixes)
217 return (a_UUID.
Version() == 4);
266 catch (
const std::exception & Oops)
294 if (
auto Link =
m_Link; Link !=
nullptr)
297 Link->Send(OutgoingData.data(), OutgoingData.size());
322 Kick(
"You can only connect to this server using a Proxy.");
332 const bool RequireForwardSecret = AllowBungee && !ForwardSecret.empty();
334 if (RequireForwardSecret)
338 if (Node.get(
"name",
"").asString() ==
"bungeeguard-token")
340 AString SentToken = Node.get(
"value",
"").asString();
342 if (ForwardSecret.compare(SentToken) == 0)
351 Kick(
"Unable to authenticate.");
356 LOG(
"A player connected through a proxy without requiring a forwarding secret. If open to the internet, this is very insecure!");
419 std::unique_ptr<cPlayer> Player;
423 Player = std::make_unique<cPlayer>(shared_from_this());
425 catch (
const std::exception & Oops)
427 LOGWARNING(
"Player \"%s\" save or statistics file loading failed: %s",
GetUsername().c_str(), Oops.what());
428 Kick(
"Contact an operator.\n\nYour player's save files could not be parsed.\nTo avoid data loss you are prevented from joining.");
442 if (
World ==
nullptr)
487 m_PingStartTime = std::chrono::steady_clock::now() + std::chrono::seconds(3);
519 int StreamedChunks = 0;
532 int RangeX, RangeZ = 0;
535 for (
int X = 0; X < 7; X++)
537 for (
int Z = 0; Z < 7; Z++)
539 int ChunkX = RangeX + ((X >= 4) ? (3 - X) : X);
540 int ChunkZ = RangeZ + ((Z >= 4) ? (3 - Z) : Z);
575 const auto StreamIfUnloaded = [
this](
const cChunkCoords Chunk)
595 for (
int i = -d; i <= d; ++i)
597 if (StreamIfUnloaded({ ChunkPosX + d, ChunkPosZ + i }) || StreamIfUnloaded({ ChunkPosX - d, ChunkPosZ + i }))
605 for (
int i = -d + 1; i < d; ++i)
607 if (StreamIfUnloaded({ ChunkPosX + i, ChunkPosZ + d }) || StreamIfUnloaded({ ChunkPosX + i, ChunkPosZ - d }))
636 const auto DiffX =
Diff((*itr).m_ChunkX, ChunkPosX);
637 const auto DiffZ =
Diff((*itr).m_ChunkZ, ChunkPosZ);
640 ChunksToRemove.push_back(*itr);
651 const auto DiffX =
Diff((*itr).m_ChunkX, ChunkPosX);
652 const auto DiffZ =
Diff((*itr).m_ChunkZ, ChunkPosZ);
664 for (cChunkCoordsList::iterator itr = ChunksToRemove.begin(); itr != ChunksToRemove.end(); ++itr)
680 if (
World->AddChunkClient(a_ChunkX, a_ChunkZ,
this))
687 World->SendChunkTo(a_ChunkX, a_ChunkZ, a_Priority,
this);
713 LOGWARNING(
"%s: Not implemented yet", __FUNCTION__);
737 auto Reply = fmt::format(FMT_STRING(
"{}{}{}{}{}"),
789 LOGWARNING(
"Got a CreativeInventoryAction packet from user \"%s\" while not in creative mode. Ignoring.",
m_Username.c_str());
794 LOGWARNING(
"Got a CreativeInventoryAction packet from user \"%s\" while not in the inventory window. Ignoring.",
m_Username.c_str());
816 if (a_Enchantment > 2)
818 LOGD(
"Player \"%s\" tried to select an invalid enchantment - hacked client?",
m_Username.c_str());
829 LOGD(
"Player \"%s\" tried to enchant without a valid window - hacked client?",
m_Username.c_str());
834 const auto BaseEnchantmentLevel = Window->
GetProperty(a_Enchantment);
841 const auto LapisRequired = a_Enchantment + 1;
862 LapisStack.AddCount(
static_cast<char>(-LapisRequired));
868 LOGD(
"Player \"%s\" selected unavailable enchantment - hacked client?",
m_Username.c_str());
899 if (a_Channel ==
"REGISTER")
909 else if (a_Channel ==
"UNREGISTER")
913 else if (a_Channel ==
"FML|HS")
920 LOGD(
"Player %s sent a plugin message on channel \"%s\", but didn't REGISTER it first",
GetUsername().c_str(), a_Channel.c_str());
936 size_t len = a_PluginChannels.size();
939 for (
size_t i = 0; i < len; i++)
941 if (a_PluginChannels[i] != std::byte(0))
947 const auto Part = a_PluginChannels.substr(first, i - first);
948 res.emplace_back(
reinterpret_cast<const char *
>(
Part.data()),
Part.size());
954 const auto Part = a_PluginChannels.substr(first, len - first);
955 res.emplace_back(
reinterpret_cast<const char *
>(
Part.data()),
Part.size());
966 for (AStringVector::const_iterator itr = a_ChannelList.begin(), end = a_ChannelList.end(); itr != end; ++itr)
978 for (AStringVector::const_iterator itr = a_ChannelList.begin(), end = a_ChannelList.end(); itr != end; ++itr)
1039 if (a_NewCommand.empty())
1041 LOGD(
"Player \"%s\" send an empty command block string - hacked client?",
m_Username.c_str());
1052 if (
World->AreCommandBlocksEnabled())
1054 World->SetCommandBlockCommand(a_BlockPos, a_NewCommand);
1070 LOGWARNING(
"%s: Not implemented yet", __FUNCTION__);
1084 if (a_ItemName.length() <= 30)
1096 FLOGD(
"HandleLeftClick: {0}; Face: {1}; Stat: {2}",
1097 a_BlockPos, a_BlockFace, a_Status
1104 Kick(
"Too many blocks were destroyed per unit time - hacked client?");
1119 const auto InterferingPosition =
AddFaceDirection(a_BlockPos, a_BlockFace);
1123 a_BlockPos = InterferingPosition;
1178 ItemHandler.OnItemShoot(
m_Player, a_BlockPos, a_BlockFace);
1229 ASSERT(!
"Unhandled DIG_STATUS");
1313 FLOGD(
"Prevented a dig / aim bug in the client (finish {0} vs start {1}, HSD: {2})",
1345 if (
cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*
m_Player, a_BlockPos, a_BlockFace, DugBlock, DugMeta))
1424 LOGD(
"Player \"%s\" sent an invalid click - hacked client?",
m_Username.c_str());
1429 a_UsedMainHand =
true;
1435 FLOGD(
"HandleRightClick: {0}, face {1}, Cursor {2}, Hand: {3}, HeldItem: {4}", a_BlockPos, a_BlockFace, a_CursorPos, a_UsedMainHand,
ItemToFullString(HeldItem));
1447 const auto & ItemHandler = HeldItem.
GetHandler();
1459 if (BlockHandler.OnUse(ChunkInterface, *
World, *
m_Player, a_BlockPos, a_BlockFace, a_CursorPos))
1469 ItemHandler.OnPlayerPlace(*
m_Player, HeldItem, a_BlockPos,
BlockType, BlockMeta, a_BlockFace, a_CursorPos);
1475 else if (ItemPlaceable)
1481 Kick(
"Too many blocks were placed / interacted with per unit time - hacked client?");
1486 ItemHandler.OnPlayerPlace(*
m_Player, HeldItem, a_BlockPos,
BlockType, BlockMeta, a_BlockFace, a_CursorPos);
1489 else if (ItemUseable)
1497 ItemHandler.OnItemUse(
World,
m_Player, PluginInterface, HeldItem, a_BlockPos, a_BlockFace);
1526 LOGD(
"Player \"%s\" sent a chat message exceeding the maximum length - hacked client?",
m_Username.c_str());
1532 if (
cRoot::Get()->GetServer()->Command(*
this, Message))
1540 if (Color.length() == 3)
1542 Color =
AString(
"@") + Color[2];
1587 #pragma clang diagnostic push
1588 #pragma clang diagnostic ignored "-Wfloat-equal"
1592 (OldPosition == a_Pos) &&
1593 (PreviousIsOnGround == a_IsOnGround)
1601 #pragma clang diagnostic pop
1612 if ((OldPosition - a_Pos).SqrLength() > 100 * 100)
1614 LOGD(
"Too far away (%0.2f), \"repairing\" the client", (OldPosition - a_Pos).Length());
1619 if (
cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*
m_Player, OldPosition, a_Pos, PreviousIsOnGround))
1661 LOGD(
"Player \"%s\" tried to spectate when not in spectator mode - hacked client?",
m_Username.c_str());
1714 LOGD(
"WindowClick: WinID %d, SlotNum %d, action: %s, Item %s x %d",
1720 if (Window ==
nullptr)
1726 Window->
Clicked(*
m_Player, a_WindowID, a_SlotNum, a_ClickAction, a_HeldItem);
1769 World->DoWithEntityByID(a_TargetEntityID, [=](
cEntity & a_Entity)
1800 if (a_Entity.IsPlayer())
1810 m_Player->NotifyNearbyWolves(static_cast<cPawn*>(&a_Entity), true);
1828 a_UsedMainHand =
true;
1834 LOGD(
"HandleUseItem: Hand: %d; HeldItem: %s", a_UsedMainHand,
ItemToFullString(HeldItem).c_str());
1836 constexpr
Vector3i DefaultBlockPos(-1, 255, -1);
1837 constexpr
Vector3i DefaultCursorPos(0, 0, 0);
1851 if (ItemHandler.IsFood() || ItemHandler.IsDrinkable(HeldItem.
m_ItemDamage))
1854 ItemHandler.IsFood() &&
1888 if ((a_Status == 1) &&
cRoot::Get()->GetServer()->ShouldRequireResourcePack())
1890 Kick(
"You must accept the resource pack");
1902 LOGD(
"Player \"%s\" tried to respawn while alive - hacked client?",
m_Username.c_str());
1929 if ((
cRoot::Get()->GetServer()->DoesAllowMultiLogin()))
1935 if (
cRoot::Get()->GetServer()->IsPlayerInQueue(a_Username))
1937 Kick(
"A player of the username is already logged in");
1944 Kick(
"A player of the username is already logged in");
1956 if (a_Username.length() > 16)
1958 Kick(
"Your username is too long (>16 characters)");
1962 if (
cRoot::Get()->GetPluginManager()->CallHookHandshake(*
this, a_Username))
1964 Kick(
"Entry denied by plugin");
1998 if (
cRoot::Get()->GetServer()->ShouldAllowMultiWorldTabCompletion())
2009 if (Results.empty())
2015 std::sort(Results.begin(), Results.end());
2080 if (!
cRoot::Get()->GetServer()->ShouldLimitPlayerBlockChanges())
2107 using namespace std::chrono_literals;
2158 if (
const auto & ResourcePackUrl =
cRoot::Get()->GetServer()->GetResourcePackUrl(); !ResourcePackUrl.empty())
2168 const auto Now = std::chrono::steady_clock::now();
2236 m_Protocol->SendAttachEntity(a_Entity, a_Vehicle);
2245 m_Protocol->SendLeashEntity(a_Entity, a_EntityLeashedTo);
2263 m_Protocol->SendBlockAction(a_BlockPos, a_Byte1, a_Byte2, a_BlockType);
2272 m_Protocol->SendBlockBreakAnim(a_EntityID, a_BlockPos, a_Stage);
2288 m_Protocol->SendBlockChange(a_BlockPos, a_BlockType, a_BlockMeta);
2298 ASSERT(!a_Changes.empty());
2310 if (a_Changes.size() == 1)
2312 const auto & Change = a_Changes[0];
2313 m_Protocol->SendBlockChange(Change.GetAbsolutePos(), Change.m_BlockType, Change.m_BlockMeta);
2317 m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes);
2326 m_Protocol->SendBossBarAdd(a_UniqueID, a_Title, a_FractionFilled, a_Color, a_DivisionType, a_DarkenSky, a_PlayEndMusic, a_CreateFog);
2335 m_Protocol->SendBossBarUpdateFlags(a_UniqueID, a_DarkenSky, a_PlayEndMusic, a_CreateFog);
2344 m_Protocol->SendBossBarUpdateStyle(a_UniqueID, a_Color, a_DivisionType);
2353 m_Protocol->SendBossBarUpdateTitle(a_UniqueID, a_Title);
2371 m_Protocol->SendBossBarUpdateHealth(a_UniqueID, a_FractionFilled);
2390 if (
World ==
nullptr)
2393 if (
World ==
nullptr)
2399 bool ShouldUsePrefixes =
World->ShouldUseChatPrefixes();
2411 if (
World ==
nullptr)
2414 if (
World ==
nullptr)
2420 bool ShouldUsePrefixes =
World->ShouldUseChatPrefixes();
2430 m_Protocol->SendChatRaw(a_MessageRaw, a_Type);
2440 if (
World ==
nullptr)
2443 if (
World ==
nullptr)
2469 if (
World ==
nullptr)
2472 if (
World ==
nullptr)
2478 auto ShouldUsePrefixes =
World->ShouldUseChatPrefixes();
2541 m_Protocol->SendCollectEntity(a_Collected, a_Collector, a_Count);
2559 m_Protocol->SendDetachEntity(a_Entity, a_PreviousVehicle);
2591 m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
2600 m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item);
2669 LOGD(
"Dropped an explosion!");
2677 const auto SoundPitchMultiplier = 1.0f + (Random.RandReal() - Random.RandReal()) * 0.2f;
2680 SendSoundEffect(
"entity.generic.explode", a_Position, 4.0f, SoundPitchMultiplier * 0.7f);
2682 const auto ParticleFormula = a_Power * 0.33f;
2683 auto Spread = ParticleFormula * 0.5f;
2684 auto ParticleCount = std::min(
static_cast<int>(ParticleFormula * 125), 600);
2687 SendParticleEffect(
"largesmoke", a_Position, {0.f, 0.f, 0.f}, Spread,
static_cast<int>(ParticleCount));
2689 Spread = ParticleFormula * 0.35f;
2690 ParticleCount = std::min(
static_cast<int>(ParticleFormula * 550), 1800);
2693 SendParticleEffect(
"explode", a_Position, {0.f, 0.f, 0.f}, Spread,
static_cast<int>(ParticleCount));
2696 m_Protocol->SendExplosion(a_Position, a_Power);
2741 m_Protocol->SendInventorySlot(a_WindowID, a_SlotNum, a_Item);
2750 m_Protocol->SendMapData(a_Map, a_DataStartX, a_DataStartY);
2759 m_Protocol->SendParticleEffect(a_ParticleName, a_Source, a_Offset, a_ParticleData, a_ParticleAmount);
2768 m_Protocol->SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data);
2786 m_Protocol->SendEntityAnimation(a_Entity, a_Animation);
2804 m_Protocol->SendPlayerListAddPlayer(a_Player);
2813 m_Protocol->SendPlayerListHeaderFooter(a_Header, a_Footer);
2822 m_Protocol->SendPlayerListRemovePlayer(a_Player);
2831 m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_CustomName);
2840 m_Protocol->SendPlayerListUpdateGameMode(a_Player);
2858 m_Protocol->SendPlayerMoveLook(a_Pos, a_Yaw, a_Pitch, a_IsRelative);
2905 LOGD(
"Spawning player \"%s\" on client \"%s\" @ %s",
2918 m_Protocol->SendPluginMessage(a_Channel, {
reinterpret_cast<const std::byte *
>(a_Message.data()), a_Message.size() });
2927 m_Protocol->SendPluginMessage(a_Channel, a_Message);
2936 m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID);
2992 m_Protocol->SendResourcePack(a_ResourcePackUrl);
3001 m_Protocol->SendScoreboardObjective(a_Name, a_DisplayName, a_Mode);
3010 m_Protocol->SendScoreUpdate(a_Objective, a_Player, a_Score, a_Mode);
3019 m_Protocol->SendDisplayObjective(a_Objective, a_Display);
3064 LOG(
"SendSoundEffect with double args is deprecated, use version with vector position parameter.");
3074 m_Protocol->SendSoundEffect(a_SoundName, a_Position, a_Volume, a_Pitch);
3083 m_Protocol->SendSoundParticleEffect(a_EffectID, a_Source, a_Data);
3119 m_Protocol->SendTabCompletionResults(a_Results);
3137 m_Protocol->SendTitleTimes(a_FadeInTicks, a_DisplayTicks, a_FadeOutTicks);
3146 m_Protocol->SendTimeUpdate(a_WorldAge, a_WorldDate, a_DoDaylightCycle);
3161 m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ);
3170 m_Protocol->SendUpdateBlockEntity(a_BlockEntity);
3184 a_Line1, a_Line2, a_Line3, a_Line4
3213 if (Window ==
nullptr)
3270 m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value);
3301 if (world !=
nullptr)
3347 LOGD(
"Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ,
static_cast<void *
>(
this));
3374 SendDisconnect(fmt::format(FMT_STRING(
"Unknown [C->S] PacketType: 0x{:x}"), a_PacketType));
3383 LOGERROR(
"Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", a_PacketType,
m_Username);
3446 m_IncomingData.append(
reinterpret_cast<const std::byte *
>(a_Data), a_Length);
3469 LOGD(
"An error has occurred on client link for %s @ %s: %d (%s). Client disconnected.",
AString ItemToString(const cItem &a_Item)
Translates a full item into a string.
AString ItemToFullString(const cItem &a_Item)
Translates a full item into a fully-specified string (including meta and count).
std::vector< sSetBlock > sSetBlockVector
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
std::list< cChunkCoords > cChunkCoordsList
unsigned char BLOCKTYPE
The datatype used by blockdata.
#define MAX_CHAT_MSG_LENGTH
Maximum number of bytes that a chat message sent by a player may consist of.
#define MAX_CHUNKS_STREAMED_PER_TICK
Maximum number of chunks to stream per tick.
#define MAX_BLOCK_CHANGE_INTERACTIONS
Maximum number of block change interactions a player can perform per tick - exceeding this causes a k...
#define MAX_EXPLOSIONS_PER_TICK
Maximum number of explosions to send this tick, server will start dropping if exceeded.
void AddFaceDirection(int &a_BlockX, int &a_BlockY, int &a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse)
Modifies the specified coords so that they point to the block adjacent to the one specified through i...
const char * ClickActionToString(int a_ClickAction)
Returns a textual representation of the click action.
T Diff(T a_Val1, T a_Val2)
@ DIG_STATUS_SWAP_ITEM_IN_HAND
eDimension
Dimension of a world.
eClickAction
Individual actions sent in the WindowClick packet.
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
MTRand & GetRandomProvider()
Returns the current thread's random number source.
std::chrono::duration< signed long long int, cTickTime::period > cTickTimeLong
std::basic_string_view< std::byte > ContiguousByteBufferView
#define FAST_FLOOR_DIV(x, div)
Faster than (int)floorf((float)x / (float)div)
T Clamp(T a_Value, T a_Min, T a_Max)
Clamp X to the specified range.
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
void LOGERROR(std::string_view a_Format, const Args &... args)
void LOGWARNING(std::string_view a_Format, const Args &... args)
void LOG(std::string_view a_Format, const Args &... args)
void LOGINFO(std::string_view a_Format, const Args &... args)
std::shared_ptr< cTCPLink > cTCPLinkPtr
AString StripColorCodes(const AString &a_Message)
Removes all control codes used by MC for colors and styles.
std::vector< AString > AStringVector
Vector3< double > Vector3d
bool IsSword(short a_ItemType)
Utilities to allow casting a cWorld to one of its interfaces without including World....
unsigned char Distance(const BlockState Block)
bool CallHookPlayerRightClick(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_CursorPos)
bool CallHookPlayerShooting(cPlayer &a_Player)
bool CallHookPlayerEating(cPlayer &a_Player)
static cPluginManager * Get(void)
Returns the instance of the Plugin Manager (there is only ever one)
bool CallHookPlayerUsingItem(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_CursorPos)
bool CallHookPlayerTossingItem(cPlayer &a_Player)
bool CallHookPlayerLeftClick(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, char a_Status)
bool CallHookPlayerSpawned(cPlayer &a_Player)
void TabCompleteCommand(const AString &a_Text, AStringVector &a_Results, cPlayer *a_Player)
Appends all commands beginning with a_Text (case-insensitive) into a_Results.
bool CallHookPlayerUsingBlock(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_CursorPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
bool CallHookPlayerUsedBlock(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_CursorPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
bool CallHookPlayerBrokenBlock(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
bool CallHookDisconnect(cClientHandle &a_Client, const AString &a_Reason)
bool CallHookPluginMessage(cClientHandle &a_Client, const AString &a_Channel, ContiguousByteBufferView a_Message)
bool CallHookPlayerUsedItem(cPlayer &a_Player, Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_CursorPos)
bool SetPrimaryEffect(cEntityEffect::eType a_Effect)
Sets the primary effect.
cEntityEffect::eType GetPrimaryEffect(void) const
bool SetSecondaryEffect(cEntityEffect::eType a_Effect)
Sets the secondary effect.
static bool IsUseableBySpectator(BLOCKTYPE Block)
Can a spectator interact with this block?
static bool IsClickedThrough(BLOCKTYPE a_Block)
Does the client pretend the block doesn't exist when clicking? For example, digging a fire will hit t...
static bool IsOneHitDig(BLOCKTYPE Block)
Is a block destroyed after a single hit? Warning: IsOneHitDig does not take into account enchantments...
static void VacateBed(cChunkInterface &a_ChunkInterface, cPlayer &a_Player)
virtual void OnDigging(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, cPlayer &a_Player, const Vector3i a_BlockPos) const
Called when the player starts digging the block.
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
static const char * LightBlue
static const char * Yellow
static const char * White
static const char * Delimiter
static const char * Italic
static const char * Green
bool IsValid(void) const
Returns true iff the chunk block data is valid (loaded / generated)
Wraps the chunk coords into a single structure.
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
Priority
Tag indicating urgency of chunk to be sent.
void SendSetRawSubTitle(const AString &a_SubTitle)
void FinishAuthenticate()
Finish logging the user in after authenticating.
bool CheckBlockInteractionsRate(void)
Returns true if the rate block interactions is within a reasonable limit (bot protection)
void StreamNextChunks()
Sends a set number of new chunks to the player on every invocation, until all chunks in the view dist...
static Vector3i s_IllegalPosition
void SendSetSubTitle(const cCompositeChat &a_SubTitle)
void HandleCommandBlockBlockChange(Vector3i a_BlockPos, const AString &a_NewCommand)
Called when the protocol receives a message, indicating that the player set a new command in the comm...
int GetUniqueID(void) const
cChannels m_PluginChannels
The plugin channels that the client has registered.
void SendHeldItemChange(int a_ItemIndex)
cPlayer * m_Player
A pointer to a World-owned player object, created in FinishAuthenticate when authentication succeeds.
int m_NumBlockChangeInteractionsThisTick
Number of place or break interactions this tick.
Vector3i m_LastPlacedSign
The positions from the last sign that the player placed.
void HandleLeftClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, UInt8 a_Status)
void HandleCommandBlockEntityChange(UInt32 a_EntityID, const AString &a_NewCommand)
Called when the protocol receives a message, indicating that the player set a new command in the comm...
cForgeHandshake m_ForgeHandshake
Forge handshake state machine.
void SendSetTitle(const cCompositeChat &a_Title)
void SetViewDistance(int a_ViewDistance)
Sets the maximal view distance.
void SetUsername(AString &&a_Username)
void HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
Called when the player enchants an Item in the Enchanting table UI.
void SendParticleEffect(const AString &a_ParticleName, Vector3f a_Source, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount)
cCriticalSection m_CSOutgoingData
Protects m_OutgoingData against multithreaded access.
void SocketClosed(void)
Called when the network socket has been closed.
void SendLeashEntity(const cEntity &a_Entity, const cEntity &a_EntityLeashedTo)
void Kick(const AString &a_Reason)
void SendChatRaw(const AString &a_MessageRaw, eChatType a_Type)
void HandleChat(const AString &a_Message)
Called when the protocol detects a chat packet.
void UnregisterPluginChannels(const AStringVector &a_ChannelList)
Removes all of the channels from the list of current plugin channels.
void SendEntityProperties(const cEntity &a_Entity)
void SendEntityHeadLook(const cEntity &a_Entity)
void SendPlayerListUpdateDisplayName(const cPlayer &a_Player, const AString &a_CustomName)
UInt32 m_PingID
ID of the last ping request sent to the client.
static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString &a_AdditionalData)
Formats the type of message with the proper color and prefix for sending to the client.
void SendDestroyEntity(const cEntity &a_Entity)
void SendScoreboardObjective(const AString &a_Name, const AString &a_DisplayName, Byte a_Mode)
Vector3i m_BlockDigAnimPos
void HandleResourcePack(UInt8 a_Status)
void HandleAnvilItemName(const AString &a_ItemName)
Called when the protocol receives a MC|ItemName plugin message, indicating that the player named an i...
int m_CurrentViewDistance
The actual view distance used, the minimum of client's requested view distance and world's max view d...
void SendChatAboveActionBar(const AString &a_Message, eMessageType a_ChatPrefix, const AString &a_AdditionalData="")
void SendWindowProperty(const cWindow &a_Window, size_t a_Property, short a_Value)
static float FASTBREAK_PERCENTAGE
The percentage how much a block has to be broken.
void SendThunderbolt(Vector3i a_BlockPos)
void SendInitRecipes(UInt32 a_RecipeId)
Send already known recipes without notification but visible in the recipe book.
cCriticalSection m_CSState
void SendPlayerListUpdateGameMode(const cPlayer &a_Player)
void SendEntityPosition(const cEntity &a_Entity)
std::atomic< int > m_TicksSinceLastPacket
Number of ticks since the last network packet was received (increased in Tick(), reset in OnReceivedD...
void SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
void SendSpawnMob(const cMonster &a_Mob)
void RegisterPluginChannels(const AStringVector &a_ChannelList)
Adds all of the channels to the list of current plugin channels.
void SendSoundParticleEffect(const EffectID a_EffectID, Vector3i a_Source, int a_Data)
virtual void OnLinkCreated(cTCPLinkPtr a_Link) override
Called when the cTCPLink for the connection is created.
void SendPlayerPermissionLevel(void)
std::unordered_set< cChunkCoords, cChunkCoordsHash > m_ChunksToSend
void PacketUnknown(UInt32 a_PacketType)
void SendBlockChange(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
void SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem &a_Item)
void SendCameraSetTo(const cEntity &a_Entity)
void HandleWindowClick(UInt8 a_WindowID, Int16 a_SlotNum, eClickAction a_ClickAction, const cItem &a_HeldItem)
void SendScoreUpdate(const AString &a_Objective, const AString &a_Player, cObjective::Score a_Score, Byte a_Mode)
void HandleLeaveBed()
Handles a player exiting his bed.
int m_NumExplosionsThisTick
Number of explosions sent this tick.
float m_BreakProgress
The fraction between 0 and 1 (or above), of how far through mining the currently mined block is.
void SendTimeUpdate(cTickTimeLong a_WorldAge, cTickTimeLong a_WorldDate, bool a_DoDaylightCycle)
void ServerTick(float a_Dt)
Called while the client is being ticked from the cServer object.
bool IsDestroyed(void) const
void SendUpdateSign(Vector3i a_BlockPos, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4)
void StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::Priority a_Priority)
Adds a single chunk to be streamed to the client; used by StreamChunks()
UInt32 m_ProtocolVersion
The version of the protocol that the client is talking, or 0 if unknown.
void SendBossBarRemove(UInt32 a_UniqueID)
void HandleKeepAlive(UInt32 a_KeepAliveID)
void PacketError(UInt32 a_PacketType)
cMultiVersionProtocol m_Protocol
void SendPluginMessage(const AString &a_Channel, std::string_view a_Message)
void HandleBlockDigStarted(Vector3i a_BlockPos, eBlockFace a_BlockFace)
Handles the DIG_STARTED dig packet:
void SendUnleashEntity(const cEntity &a_Entity)
AStringVector BreakApartPluginChannels(ContiguousByteBufferView a_PluginChannels)
Converts the protocol-formatted channel list (NUL-separated) into a proper string vector.
bool m_ProxyConnection
True if player connected from a proxy (Bungee / Velocity)
void SendPlayerAbilities(void)
void HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsOnGround)
std::unordered_set< cChunkCoords, cChunkCoordsHash > m_LoadedChunks
void HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_Cursor, bool a_UsedMainHand)
void SendSpawnEntity(const cEntity &a_Entity)
void HandlePluginMessage(const AString &a_Channel, ContiguousByteBufferView a_Message)
ContiguousByteBuffer m_IncomingData
Queue for the incoming data received on the link until it is processed in ProcessProtocolIn().
bool HandleHandshake(const AString &a_Username)
Called when the protocol handshake has been received (for protocol versions that support it; otherwis...
void SendResetTitle(void)
void SendWindowOpen(const cWindow &a_Window)
std::atomic< eState > m_State
The current (networking) state of the client.
void ProxyInit(const AString &a_IPString, const cUUID &a_UUID)
Function to mark bungee / proxy connection on this client, and to add proxy-related data.
void SendWeather(eWeather a_Weather)
void SendPlayerListHeaderFooter(const cCompositeChat &a_Header, const cCompositeChat &a_Footer)
cTCPLinkPtr m_Link
The link that is used for network communication.
void HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
cCriticalSection m_CSIncomingData
Protects m_IncomingData against multithreaded access.
void SendGameMode(eGameMode a_GameMode)
virtual void OnRemoteClosed(void) override
Called when the remote end closes the connection.
void HandleUpdateSign(Vector3i a_BlockPos, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4)
static const int MIN_VIEW_DISTANCE
void SetProperties(const Json::Value &a_Properties)
Sets the player's properties, such as skin image and signature.
static bool IsUUIDOnline(const cUUID &a_UUID)
Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID.
void SendWindowClose(const cWindow &a_Window)
std::chrono::milliseconds m_TimeSinceLastUnloadCheck
The time since UnloadOutOfRangeChunks was last called.
bool IsWithinReach(Vector3i a_Position) const
Returns whether the player could in fact reach the position they're attempting to interact with.
void SendBlockBreakAnim(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage)
std::chrono::steady_clock::duration m_Ping
Duration of the last completed client ping.
void HandleSteerVehicle(float Forward, float Sideways)
void SendSoundEffect(const AString &a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
void SendEntityMetadata(const cEntity &a_Entity)
void SendPaintingSpawn(const cPainting &a_Painting)
void SendRemoveEntityEffect(const cEntity &a_Entity, int a_EffectID)
void UnloadOutOfRangeChunks(void)
Remove all loaded chunks that are no longer in range.
void HandleStartElytraFlight()
Handles a player starting elytra flight while falling.
void HandleUseItem(bool a_UsedMainHand)
void HandleSprint(bool a_IsSprinting)
Handles a player sprinting or slowing back down.
cClientHandle(const AString &a_IPString, int a_ViewDistance)
Creates a new client with the specified IP address in its description and the specified initial view ...
void SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks)
void ProcessProtocolIn(void)
Processes the data in the network input buffer.
void SendPlayerListUpdatePing()
void SendPlayerSpawn(const cPlayer &a_Player)
const AString & GetUsername(void) const
void SendTabCompletionResults(const AStringVector &a_Results)
void HandlePlayerMove(Vector3d a_Pos, bool a_IsOnGround)
Verifies and sets player position, performing relevant checks.
void ProcessProtocolOut()
Flushes all buffered outgoing data to the network.
void SendPlayerMoveLook(void)
void SendEntityVelocity(const cEntity &a_Entity)
@ csConnected
The client has just connected, waiting for their handshake / login.
@ csAuthenticating
The client has logged in, waiting for external authentication.
@ csDestroyed
The client has been destroyed, the destructor is to be called from the owner thread.
@ csPlaying
Normal gameplay.
@ csDownloadingWorld
The client is waiting for chunks, we're waiting for the loader to provide and send them.
const AString & GetIPString(void) const
static cUUID GenerateOfflineUUID(const AString &a_Username)
Generates an UUID based on the player name provided.
void SendStatistics(const StatisticsManager &a_Manager)
void HandleTabCompletion(const AString &a_Text)
void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector &a_Changes)
ContiguousByteBuffer m_OutgoingData
Buffer for storing outgoing data from any thread; will get sent in ProcessProtocolOut() at the end of...
void SendBossBarUpdateStyle(UInt32 a_UniqueID, BossBarColor a_Color, BossBarDivisionType a_DivisionType)
void SendEntityEquipment(const cEntity &a_Entity, short a_SlotNum, const cItem &a_Item)
void HandlePlayerAbilities(bool a_IsFlying, float FlyingSpeed, float WalkingSpeed)
void HandleNPCTrade(int a_SlotNum)
Called when the protocol receives a MC|TrSel packet, indicating that the player used a trade in the N...
Vector3i m_LastDigBlockPos
void HandleSpectate(const cUUID &a_PlayerUUID)
void HandleBlockDigFinished(Vector3i a_BlockPos, eBlockFace a_BlockFace)
Handles the DIG_FINISHED dig packet:
void SetIPString(const AString &a_IPString)
Sets the IP string that the client is using.
void SendEntityEffect(const cEntity &a_Entity, int a_EffectID, int a_Amplifier, int a_Duration)
cChunkCoords m_CachedSentChunk
This is an optimization which saves you an iteration of m_SentChunks if you just want to know whether...
void SendBlockAction(Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType)
void SendBossBarUpdateHealth(UInt32 a_UniqueID, float a_FractionFilled)
void HandleBeaconSelection(unsigned a_PrimaryEffect, unsigned a_SecondaryEffect)
Called when the protocol receives a MC|Beacon plugin message, indicating that the player set an effec...
int m_RequestedViewDistance
The requested view distance from the player.
bool CheckMultiLogin(const AString &a_Username)
Kicks the client if the same username is already logged in.
cUUID m_UUID
Contains the UUID used by Mojang to identify the player's account.
void RemoveFromWorld(void)
Called when the player moves into a different world.
void SendDetachEntity(const cEntity &a_Entity, const cEntity &a_PreviousVehicle)
cChunkCoordsList m_SentChunks
void SendPlayerListAddPlayer(const cPlayer &a_Player)
void SendBossBarUpdateFlags(UInt32 a_UniqueID, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog)
void SendExplosion(Vector3f a_Position, float a_Power)
void SendMapData(const cMap &a_Map, int a_DataStartX, int a_DataStartY)
void HandleWindowClose(UInt8 a_WindowID)
cCriticalSection m_CSChunkLists
void SendDisconnect(const AString &a_Reason)
void SendRespawn(eDimension a_Dimension, bool a_IsRespawningFromDeath)
virtual ~cClientHandle() override
void SendEntityLook(const cEntity &a_Entity)
static AString FormatChatPrefix(bool ShouldAppendChatPrefixes, const AString &a_ChatPrefixS, const AString &m_Color1, const AString &m_Color2)
void HandleCrouch(bool a_IsCrouching)
Handles a player sneaking or unsneaking.
cPlayer * GetPlayer(void)
void PacketBufferFull(void)
void HandleSlotSelected(Int16 a_SlotNum)
int m_UniqueID
ID used for identification during authenticating.
void HandlePlayerMoveLook(Vector3d a_Pos, float a_Rotation, float a_Pitch, bool a_IsOnGround)
void SendExperienceOrb(const cExpOrb &a_ExpOrb)
bool m_HasSentPlayerChunk
Set to true when the chunk where the player is is sent to the client.
void SendCollectEntity(const cEntity &a_Collected, const cEntity &a_Collector, unsigned a_Count)
bool HandleLogin()
Called when the protocol has finished logging the user in.
virtual void OnReceivedData(const char *a_Data, size_t a_Length) override
Called when there's data incoming from the remote peer.
void SendEditSign(Vector3i a_BlockPos)
bool m_HasSentDC
True if a Disconnect packet has been sent in either direction.
void SendBossBarAdd(UInt32 a_UniqueID, const cCompositeChat &a_Title, float a_FractionFilled, BossBarColor a_Color, BossBarDivisionType a_DivisionType, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog)
void SendResourcePack(const AString &a_ResourcePackUrl)
void SendPlayerPosition(void)
void SetUUID(const cUUID &a_UUID)
Sets the player's UUID, as used by the protocol.
void SendExperience(void)
void SendWholeInventory(const cWindow &a_Window)
void FinishDigAnimation()
The clients will receive a finished dig animation.
void Tick(std::chrono::milliseconds a_Dt)
Called while the client is being ticked from the world via its cPlayer object.
void SendUnlockRecipe(UInt32 a_RecipeId)
Send a newly discovered recipe to show the notification and unlock in the recipe book.
void SendDisplayObjective(const AString &a_Objective, cScoreboard::eDisplaySlot a_Display)
void SendChat(const AString &a_Message, eMessageType a_ChatPrefix, const AString &a_AdditionalData="")
void SendSetRawTitle(const AString &a_Title)
void HandleCraftRecipe(UInt32 a_RecipeId)
Called when a recipe from the recipe book is selected.
bool HasPluginChannel(const AString &a_PluginChannel)
bool BungeeAuthenticate()
Authenticates the specified user with the bungee proxy server.
bool SetState(eState a_NewState)
Called to update m_State.
void HandleOpenHorseInventory()
Handles a player opening his inventory while riding a horse.
void SendPlayerListRemovePlayer(const cPlayer &a_Player)
void SendData(ContiguousByteBufferView a_Data)
void SendChunkData(int a_ChunkX, int a_ChunkZ, ContiguousByteBufferView a_ChunkData)
void SendUpdateBlockEntity(cBlockEntity &a_BlockEntity)
void HandleAnimation(bool a_SwingMainHand)
Called when the protocol receives a (hand swing) animation packet.
void SendChatSystem(const AString &a_Message, eMessageType a_ChatPrefix, const AString &a_AdditionalData="")
void SendEntityAnimation(const cEntity &a_Entity, EntityAnimation a_Animation)
bool WantsSendChunk(int a_ChunkX, int a_ChunkZ)
Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend)
const Json::Value & GetProperties(void) const
void SendAttachEntity(const cEntity &a_Entity, const cEntity &a_Vehicle)
void Authenticate(AString &&a_Name, const cUUID &a_UUID, Json::Value &&a_Properties)
Authenticates ourselves, called by cAuthenticator supplying player details from Mojang.
void HandleCreativeInventory(Int16 a_SlotNum, const cItem &a_HeldItem, eClickAction a_ClickAction)
Called when the client clicks the creative inventory window.
std::chrono::steady_clock::time_point m_PingStartTime
Time of the last ping request sent to the client.
virtual void OnError(int a_ErrorCode, const AString &a_ErrorMsg) override
Called when an error is detected on the connection.
void AddWantedChunk(int a_ChunkX, int a_ChunkZ)
Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend)
void SendBossBarUpdateTitle(UInt32 a_UniqueID, const cCompositeChat &a_Title)
Container for a single chat message composed of multiple functional parts.
void UnderlineUrls(void)
Adds the "underline" style to each part that is an URL.
void ParseText(const AString &a_ParseText)
Parses text into various parts, adds those.
void AddTextPart(const AString &a_Message, const AString &a_Style="")
Adds a plain text part, with optional style.
void SetPitch(double a_Pitch)
int GetChunkZ(void) const
void SteerVehicle(float a_Forward, float a_Sideways)
void SetHeadYaw(double a_HeadYaw)
void Detach(void)
Detaches from the currently attached entity, if any.
void SetYaw(double a_Yaw)
cChunk * GetParentChunk()
Returns the chunk responsible for ticking this entity.
int GetChunkX(void) const
virtual void TeleportToEntity(cEntity &a_Entity)
Teleports to the entity specified.
double GetPosX(void) const
void SetPosition(double a_PosX, double a_PosY, double a_PosZ)
double GetPosZ(void) const
bool IsMinecart(void) const
bool Initialize(OwnedEntity a_Self, cWorld &a_EntityWorld)
Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed).
UInt32 GetUniqueID(void) const
void TakeDamage(cEntity &a_Attacker)
Makes this pawn take damage from an attack by a_Attacker.
float GetHealth(void) const
Returns the health of this entity.
virtual void OnRightClicked(cPlayer &a_Player)
Called when the specified player right-clicks this entity.
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Vector3d GetLookVector(void) const
cWorld * GetWorld(void) const
eType
All types of entity effects (numbers correspond to protocol / storage types)
ePayload GetPayload(void) const
void SendMessage(const AString &a_Message)
void SetFlying(bool a_ShouldFly)
Starts or stops flying, broadcasting the state change.
const AString & GetName(void) const
void UpdateMovementStats(const Vector3d &a_DeltaPos, bool a_PreviousIsOnGround)
Update movement-related statistics.
AString GetColor(void) const
Returns the full color code to use for this player, based on their rank.
bool IsFrozen()
Is the player frozen?
StatisticsManager & GetStatistics()
Return the associated statistic and achievement manager.
int GetCurrentXp(void)
Gets the current experience.
void CloseWindow(bool a_CanRefuse=true)
Closes the current window, resets current window to m_InventoryWindow.
const cItem & GetEquippedItem(void) const
float GetXpPercentage(void) const
Gets the experience bar percentage - XpP.
void SpectateEntity(cEntity *a_Target)
Spectates the target entity.
void AbortEating(void)
Aborts the current eating operation.
void AddKnownItem(const cItem &a_Item)
Adds an Item to the list of known items.
bool IsGameModeSurvival(void) const
Returns true if the player is in Survival mode, either explicitly, or by inheriting from current worl...
void OpenHorseInventory()
Opens the inventory of any tame horse the player is riding.
int DeltaExperience(int a_Xp_delta)
AString GetSuffix(void) const
Returns the player name suffix, may contain @ format directives.
int GetXpLevel(void) const
Gets the current level - XpLevel.
const AString & GetLoadedWorldName() const
virtual bool IsCrouched(void) const override
void TossEquippedItem(char a_Amount=1)
tosses the item in the selected hotbar slot
bool IsGameModeCreative(void) const
Returns true if the player is in Creative mode, either explicitly, or by inheriting from current worl...
virtual cItem GetOffHandEquipedItem(void) const override
Returns the currently offhand equipped item; empty item if none.
cInventory & GetInventory(void)
void AddFoodExhaustion(double a_Exhaustion)
Adds the specified exhaustion to m_FoodExhaustion.
void PermuteEnchantmentSeed()
Permute the seed for enchanting related PRNGs, don't use this for other purposes.
bool IsGameModeSpectator(void) const
Returns true if the player is in Spectator mode, either explicitly, or by inheriting from current wor...
bool CanInstantlyMine(BLOCKTYPE a_Block)
Given tool, enchantments, status effects, and world position returns whether a_Block would be instant...
bool HasPermission(const AString &a_Permission) const
const std::set< UInt32 > & GetKnownRecipes() const
Gets the set of IDs for recipes this player has discovered.
void SetElytraFlight(bool a_ShouldElytraFly)
Starts or stops elytra flight, if our current body stance permits, broadcasting the state change.
cWindow * GetWindow(void)
void StartEating(void)
Starts eating the currently equipped item.
void SetCrouch(bool a_ShouldCrouch)
Starts or stops crouching, if our current body stance permits, broadcasting the state change.
void SendBlocksAround(Vector3i a_BlockPos, int a_Range=1)
Sends the block in the specified range around the specified coord to the client as a block change pac...
void CloseWindowIfID(char a_WindowID, bool a_CanRefuse=true)
Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow.
Vector3d GetEyePosition(void) const
bool IsSatiated(void) const
Returns true if the player is satiated, i.
void SetSprint(bool a_ShouldSprint)
Starts or stops sprinting, if our current body stance permits, broadcasting the state change.
AString GetPrefix(void) const
Returns the player name prefix, may contain @ format directives.
bool IsGameModeAdventure(void) const
Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current wor...
void SetTouchGround(bool a_bTouchGround)
static int XpForLevel(int a_Level)
Calculates the amount of XP needed for a given level Ref: https://minecraft.wiki/w/XP.
virtual bool IsOnGround(void) const override
Returns whether the entity is on ground or not.
float GetMiningProgressPerTick(BLOCKTYPE a_Block)
Returns the progress mined per tick for the block a_Block as a fraction (1 would be completely mined)...
void UseEquippedItem(short a_Damage=1)
Damage the player's equipped item by a_Damage, possibly less if the equipped item is enchanted.
This class represents the player's inventory The slots are divided into three areas:
void SetEquippedSlotNum(int a_SlotNum)
Sets equiped item to the a_SlotNum slot number.
void SendEquippedSlot()
Sends the equipped item slot to the client.
void SetShieldSlot(const cItem &a_Item)
Sets current item in shield slot.
const cItem & GetEquippedItem(void) const
Returns current equiped item.
const cItem & GetShieldSlot() const
Returns current item in shield slot.
void SetEquippedItem(const cItem &a_Item)
Sets current item in the equipped hotbar slot.
const cItemHandler & GetHandler(void) const
Returns the cItemHandler responsible for this item type.
bool IsEmpty(void) const
Returns true if the item represents an empty stack - either the type is invalid, or count is zero.
virtual void OnItemShoot(cPlayer *, const Vector3i a_BlockPos, eBlockFace a_BlockFace) const
Called when the client sends the SHOOT status in the lclk packet (releasing the bow).
virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, const cItem &a_HeldItem, const Vector3i a_ClickedBlockPos, eBlockFace a_ClickedBlockFace) const
Called while the player digs a block using this item.
Encapsulates an in-game world map.
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
void Authenticate(int a_ClientID, std::string_view a_Username, std::string_view a_ServerHash)
Queues a request for authenticating a user.
void BeginForgeHandshake(cClientHandle &a_Client)
Begin the Forge Modloader Handshake (FML|HS) sequence.
bool IsForgeClient
True if the client advertised itself as a Forge client.
void DataReceived(cClientHandle &a_Client, ContiguousByteBufferView a_Data)
Process received data from the client advancing the Forge handshake.
void HandleOutgoingData(ContiguousByteBuffer &a_Data)
Allows the protocol (if any) to do a final pass on outgiong data, possibly modifying the provided buf...
void HandleIncomingData(cClientHandle &a_Client, ContiguousByteBuffer &a_Data)
Directs incoming protocol data along the correct pathway, depending on the state of the version recog...
void SendDisconnect(cClientHandle &a_Client, const AString &a_Reason)
Sends a disconnect to the client as a result of a recognition error.
bool VersionRecognitionSuccessful()
Returns if we contain a concrete protocol corresponding to the client's protocol version.
cServer * GetServer(void)
void BroadcastChat(const AString &a_Message, eMessageType a_ChatPrefix=mtCustom)
Sends a chat message to all connected clients (in all worlds)
AStringVector GetPlayerTabCompletionMultiWorld(const AString &a_Text)
Returns the completions for a player name across all worlds.
void SendPlayerLists(cPlayer *a_DestPlayer)
Send playerlist of all worlds to player.
cAuthenticator & GetAuthenticator(void)
cWorld * GetDefaultWorld(void)
cPluginManager * GetPluginManager(void)
void BroadcastChatJoin(const AString &a_Message)
cWorld * GetWorld(const AString &a_WorldName)
Returns a pointer to the world specified.
void BroadcastPlayerListsAddPlayer(const cPlayer &a_Player, const cClientHandle *a_Exclude=nullptr)
Broadcast playerlist addition through all worlds.
void PlayerCreated()
Notifies the server that a player was created; the server uses this to adjust the number of players.
size_t GetMaxPlayers(void) const
const AString & GetProxySharedSecret(void) const
const AString & GetDescription(void) const
bool ShouldAllowBungeeCord(void) const
Returns true if BungeeCord logins (that specify the player's UUID) are allowed.
void ClientMovedToWorld(const cClientHandle *a_Client)
Don't tick a_Client anymore, it will be ticked from its cPlayer instead.
size_t GetNumPlayers(void) const
Class that manages the statistics and achievements of a single player.
cBeaconEntity * GetBeaconEntity(void) const
short GetProperty(size_t a_Property)
Return the level requirement of the given enchantment slot.
cSlotAreaEnchanting * m_SlotArea
virtual const cItem * GetSlot(int a_SlotNum, cPlayer &a_Player) const override
Called to retrieve an item in the specified slot for the specified player.
virtual void SetSlot(int a_SlotNum, cPlayer &a_Player, const cItem &a_Item) override
Called to set an item in the specified slot for the specified player.
cItem SelectEnchantedOption(size_t a_EnchantOption)
void SetSlot(cPlayer &a_Player, int a_SlotNum, const cItem &a_Item)
Sets the item to the specified slot for the specified player.
const cItem * GetSlot(cPlayer &a_Player, int a_SlotNum) const
Returns the item at the specified slot for the specified player.
char GetWindowID(void) const
virtual void Clicked(cPlayer &a_Player, int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem &a_ClickedItem)
Handles a click event from a player.
int GetWindowType(void) const
static cUUID GenerateVersion3(const AString &a_Name)
Generates a version 3, variant 1 UUID based on the md5 hash of a_Name.
bool IsNil() const
Returns true if this contains the "nil" UUID with all bits set to 0.
UInt8 Version() const
Returns the version number of the UUID.
void Set(T a_x, T a_y, T a_z)
bool Equals(const Vector3< T > &a_Rhs) const
bool DoWithPlayerByUUID(const cUUID &a_PlayerUUID, cPlayerListCallback a_Callback)
Finds the player over his uuid and calls the callback.
void TabCompleteUserName(const AString &a_Text, AStringVector &a_Results)
Appends all usernames starting with a_Text (case-insensitive) into Results.
bool IsPVPEnabled(void) const
virtual void BroadcastEntityAnimation(const cEntity &a_Entity, EntityAnimation a_Animation, const cClientHandle *a_Exclude=nullptr) override
BLOCKTYPE GetBlock(Vector3i a_BlockPos) const
Returns the block type at the specified position.
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Removes client from the chunk specified.
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Retrieves the block type and meta at the specified coords.
int GetMaxViewDistance(void) const
virtual eDimension GetDimension(void) const override
virtual void BroadcastEntityEquipment(const cEntity &a_Entity, short a_SlotNum, const cItem &a_Item, const cClientHandle *a_Exclude=nullptr) override
bool SetSignLines(Vector3i a_BlockPos, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4, cPlayer *a_Player=nullptr)
Sets the sign text, asking plugins for permission first.
virtual void BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, Int8 a_Stage, const cClientHandle *a_Exclude=nullptr) override
cChunkMap * GetChunkMap(void)