2013-09-16 19:16:05 +01:00
2012-06-14 13:06:06 +00:00
// cClientHandle.h
// Interfaces to the cClientHandle class representing a client connected to this server. The client need not be a player yet
#pragma once
2015-01-24 20:17:00 +01:00
#include "OSSupport/Network.h"
2012-08-26 16:20:08 +00:00
#include "Defines.h"
2014-03-11 16:01:17 +02:00
#include "Vector3.h"
2012-06-14 13:06:06 +00:00
#include "ChunkDef.h"
2012-08-17 10:18:07 +00:00
#include "ByteBuffer.h"
2014-01-21 15:58:17 +02:00
#include "Scoreboard.h"
2014-02-18 20:50:08 +02:00
#include "Map.h"
2014-04-12 14:58:46 +02:00
#include "Enchantments.h"
2014-04-13 22:15:10 +02:00
#include "UI/SlotArea.h"
2014-07-16 00:03:47 +01:00
#include "json/json.h"
2014-10-06 21:27:53 +02:00
#include "ChunkSender.h"
2015-11-23 23:39:19 +00:00
#include "EffectID.h"
2012-06-14 13:06:06 +00:00
2015-03-21 17:17:26 +00:00
#include <array>
2015-06-27 12:10:24 +01:00
#include <atomic>
2012-06-14 13:06:06 +00:00
2015-01-24 20:17:00 +01:00
// fwd:
2012-08-27 17:31:16 +00:00
class cChunkDataSerializer ;
2012-08-19 11:51:17 +00:00
class cInventory ;
2012-08-27 17:31:16 +00:00
class cMonster ;
2012-08-19 21:14:45 +00:00
class cPawn ;
2013-11-25 21:43:43 +01:00
class cExpOrb ;
2014-02-18 00:16:03 +00:00
class cPainting ;
2012-08-24 07:58:26 +00:00
class cPickup ;
2012-08-27 17:31:16 +00:00
class cPlayer ;
class cProtocol ;
class cWindow ;
2012-12-26 09:12:00 +00:00
class cFallingBlock ;
2013-01-12 04:46:01 +00:00
class cItemHandler ;
2013-08-14 10:24:34 +02:00
class cWorld ;
2014-02-15 23:16:44 +01:00
class cCompositeChat ;
2014-05-11 14:57:06 +03:00
class cStatManager ;
2015-01-24 20:17:00 +01:00
class cClientHandle ;
typedef SharedPtr < cClientHandle > cClientHandlePtr ;
2012-06-14 13:06:06 +00:00
2012-12-24 22:09:01 +00:00
2015-01-24 20:17:00 +01:00
class cClientHandle // tolua_export
: public cTCPLink :: cCallbacks
2014-07-17 16:33:09 +02:00
{ // tolua_export
2015-01-24 20:17:00 +01:00
public : // tolua_export
#if defined(ANDROID_NDK)
static const int DEFAULT_VIEW_DISTANCE = 4 ; // The default ViewDistance (used when no value is set in Settings.ini)
#else
static const int DEFAULT_VIEW_DISTANCE = 10 ;
#endif
2014-07-23 20:28:56 +02:00
static const int MAX_VIEW_DISTANCE = 32 ;
static const int MIN_VIEW_DISTANCE = 1 ;
2016-02-05 23:45:45 +02:00
2015-01-24 20:17:00 +01:00
/** Creates a new client with the specified IP address in its description and the specified initial view distance. */
cClientHandle ( const AString & a_IPString , int a_ViewDistance );
2012-09-25 08:23:19 +00:00
virtual ~ cClientHandle ();
2012-06-14 13:06:06 +00:00
2014-09-07 22:35:22 +02:00
const AString & GetIPString ( void ) const { return m_IPString ; } // tolua_export
2016-02-05 23:45:45 +02:00
2014-09-17 11:07:42 +02:00
/** Sets the IP string that the client is using. Overrides the IP string that was read from the socket.
Used mainly by BungeeCord compatibility code. */
void SetIPString ( const AString & a_IPString ) { m_IPString = a_IPString ; }
2016-02-05 23:45:45 +02:00
2014-07-17 16:33:09 +02:00
cPlayer * GetPlayer ( void ) { return m_Player ; } // tolua_export
2012-06-14 13:06:06 +00:00
2014-07-30 13:52:51 +02:00
/** Returns the player's UUID, as used by the protocol, in the short form (no dashes) */
2014-07-17 16:33:09 +02:00
const AString & GetUUID ( void ) const { return m_UUID ; } // tolua_export
2016-02-05 23:45:45 +02:00
2014-09-17 11:07:42 +02:00
/** Sets the player's UUID, as used by the protocol. Short UUID form (no dashes) is expected.
Used mainly by BungeeCord compatibility code - when authenticating is done on the BungeeCord server
and the results are passed to MCS running in offline mode. */
void SetUUID ( const AString & a_UUID ) { ASSERT ( a_UUID . size () == 32 ); m_UUID = a_UUID ; }
2014-07-14 19:49:31 +01:00
2014-07-16 00:03:47 +01:00
const Json :: Value & GetProperties ( void ) const { return m_Properties ; }
2016-02-05 23:45:45 +02:00
2014-09-17 11:07:42 +02:00
/** Sets the player's properties, such as skin image and signature.
Used mainly by BungeeCord compatibility code - property querying is done on the BungeeCord server
and the results are passed to MCS running in offline mode. */
void SetProperties ( const Json :: Value & a_Properties ) { m_Properties = a_Properties ; }
2016-02-05 23:45:45 +02:00
2014-04-14 22:52:59 +02:00
/** Generates an UUID based on the username stored for this client, and stores it in the m_UUID member.
This is used for the offline (non-auth) mode, when there's no UUID source.
Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same.
Internally calls the GenerateOfflineUUID static function. */
void GenerateOfflineUUID ( void );
2016-02-05 23:45:45 +02:00
2014-04-14 20:21:00 +02:00
/** Generates an UUID based on the player name provided.
This is used for the offline (non-auth) mode, when there's no UUID source.
2014-06-21 22:13:35 +02:00
Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same.
2014-07-30 13:52:51 +02:00
Returns a 32-char UUID (no dashes). */
2014-04-14 22:52:59 +02:00
static AString GenerateOfflineUUID ( const AString & a_Username ); // tolua_export
2016-02-05 23:45:45 +02:00
2014-06-21 22:13:35 +02:00
/** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID.
We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart.
Accepts both 32-char and 36-char UUIDs (with and without dashes).
If the string given is not a valid UUID, returns false. */
static bool IsUUIDOnline ( const AString & a_UUID ); // tolua_export
2016-02-05 23:45:45 +02:00
2015-07-31 16:49:10 +02:00
/** Formats the type of message with the proper color and prefix for sending to the client. */
2014-05-19 21:16:29 +01:00
static AString FormatMessageType ( bool ShouldAppendChatPrefixes , eMessageType a_ChatPrefix , const AString & a_AdditionalData );
2016-02-05 23:45:45 +02:00
2014-05-19 21:16:29 +01:00
static AString FormatChatPrefix ( bool ShouldAppendChatPrefixes , AString a_ChatPrefixS , AString m_Color1 , AString m_Color2 );
2014-04-13 13:04:56 +02:00
2014-07-16 00:03:47 +01:00
void Kick ( const AString & a_Reason ); // tolua_export
/** Authenticates the specified user, called by cAuthenticator */
void Authenticate ( const AString & a_Name , const AString & a_UUID , const Json :: Value & a_Properties );
2012-06-14 13:06:06 +00:00
2014-10-06 21:27:53 +02:00
/** This function sends a new unloaded chunk to the player. Returns true if all chunks are loaded. */
bool StreamNextChunk ();
2014-10-02 23:50:41 +02:00
/** Remove all loaded chunks that are no longer in range */
void UnloadOutOfRangeChunks ( void );
2016-02-05 23:45:45 +02:00
2012-06-14 13:06:06 +00:00
// Removes the client from all chunks. Used when switching worlds or destroying the player
void RemoveFromAllChunks ( void );
2016-02-05 23:45:45 +02:00
2012-11-11 14:00:58 +00:00
inline bool IsLoggedIn ( void ) const { return ( m_State >= csAuthenticating ); }
2012-06-14 13:06:06 +00:00
2014-02-20 23:24:39 +01:00
/** Called while the client is being ticked from the world via its cPlayer object */
2012-06-14 13:06:06 +00:00
void Tick ( float a_Dt );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Called while the client is being ticked from the cServer object */
2013-12-16 10:41:35 +01:00
void ServerTick ( float a_Dt );
2012-06-14 13:06:06 +00:00
2012-11-11 14:00:58 +00:00
void Destroy ( void );
2016-02-05 23:45:45 +02:00
2012-11-11 14:00:58 +00:00
bool IsPlaying ( void ) const { return ( m_State == csPlaying ); }
bool IsDestroyed ( void ) const { return ( m_State == csDestroyed ); }
bool IsDestroying ( void ) const { return ( m_State == csDestroying ); }
2012-06-14 13:06:06 +00:00
2013-07-07 13:06:06 +00:00
// The following functions send the various packets:
// (Please keep these alpha-sorted)
2014-09-18 18:50:17 +02:00
void SendAttachEntity ( const cEntity & a_Entity , const cEntity * a_Vehicle );
void SendBlockAction ( int a_BlockX , int a_BlockY , int a_BlockZ , char a_Byte1 , char a_Byte2 , BLOCKTYPE a_BlockType );
2015-03-21 16:11:57 +01:00
void SendBlockBreakAnim ( UInt32 a_EntityID , int a_BlockX , int a_BlockY , int a_BlockZ , char a_Stage );
2014-09-18 18:50:17 +02:00
void SendBlockChange ( int a_BlockX , int a_BlockY , int a_BlockZ , BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta ); // tolua_export
void SendBlockChanges ( int a_ChunkX , int a_ChunkZ , const sSetBlockVector & a_Changes );
void SendChat ( const AString & a_Message , eMessageType a_ChatPrefix , const AString & a_AdditionalData = "" );
void SendChat ( const cCompositeChat & a_Message );
2015-06-02 19:59:46 +02:00
void SendChatAboveActionBar ( const AString & a_Message , eMessageType a_ChatPrefix , const AString & a_AdditionalData = "" );
void SendChatAboveActionBar ( const cCompositeChat & a_Message );
void SendChatSystem ( const AString & a_Message , eMessageType a_ChatPrefix , const AString & a_AdditionalData = "" );
void SendChatSystem ( const cCompositeChat & a_Message );
2014-09-18 18:50:17 +02:00
void SendChunkData ( int a_ChunkX , int a_ChunkZ , cChunkDataSerializer & a_Serializer );
void SendCollectEntity ( const cEntity & a_Entity , const cPlayer & a_Player );
void SendDestroyEntity ( const cEntity & a_Entity );
void SendDisconnect ( const AString & a_Reason );
2014-10-01 12:14:38 +02:00
void SendDisplayObjective ( const AString & a_Objective , cScoreboard :: eDisplaySlot a_Display );
2014-09-18 18:50:17 +02:00
void SendEditSign ( int a_BlockX , int a_BlockY , int a_BlockZ );
2014-10-01 12:14:38 +02:00
void SendEntityAnimation ( const cEntity & a_Entity , char a_Animation ); // tolua_export
2014-09-18 18:50:17 +02:00
void SendEntityEffect ( const cEntity & a_Entity , int a_EffectID , int a_Amplifier , short a_Duration );
void SendEntityEquipment ( const cEntity & a_Entity , short a_SlotNum , const cItem & a_Item );
void SendEntityHeadLook ( const cEntity & a_Entity );
void SendEntityLook ( const cEntity & a_Entity );
void SendEntityMetadata ( const cEntity & a_Entity );
void SendEntityProperties ( const cEntity & a_Entity );
void SendEntityRelMove ( const cEntity & a_Entity , char a_RelX , char a_RelY , char a_RelZ );
void SendEntityRelMoveLook ( const cEntity & a_Entity , char a_RelX , char a_RelY , char a_RelZ );
void SendEntityStatus ( const cEntity & a_Entity , char a_Status );
void SendEntityVelocity ( const cEntity & a_Entity );
2014-10-01 12:14:38 +02:00
void SendExperience ( void );
void SendExperienceOrb ( const cExpOrb & a_ExpOrb );
2014-09-18 18:50:17 +02:00
void SendExplosion ( double a_BlockX , double a_BlockY , double a_BlockZ , float a_Radius , const cVector3iArray & a_BlocksAffected , const Vector3d & a_PlayerMotion );
void SendGameMode ( eGameMode a_GameMode );
void SendHealth ( void );
2015-04-08 00:41:19 +10:00
void SendHideTitle ( void );
2014-09-18 18:50:17 +02:00
void SendInventorySlot ( char a_WindowID , short a_SlotNum , const cItem & a_Item );
2015-06-30 15:50:15 +01:00
void SendMapData ( const cMap & a_Map , int a_DataStartX , int a_DataStartY );
2014-09-18 18:50:17 +02:00
void SendPaintingSpawn ( const cPainting & a_Painting );
void SendParticleEffect ( const AString & a_ParticleName , float a_SrcX , float a_SrcY , float a_SrcZ , float a_OffsetX , float a_OffsetY , float a_OffsetZ , float a_ParticleData , int a_ParticleAmount );
2015-03-21 17:17:26 +00:00
void SendParticleEffect ( const AString & a_ParticleName , const Vector3f a_Src , const Vector3f a_Offset , float a_ParticleData , int a_ParticleAmount , std :: array < int , 2 > a_Data );
2014-10-01 12:14:38 +02:00
void SendPickupSpawn ( const cPickup & a_Pickup );
2014-09-18 18:50:17 +02:00
void SendPlayerAbilities ( void );
void SendPlayerListAddPlayer ( const cPlayer & a_Player );
void SendPlayerListRemovePlayer ( const cPlayer & a_Player );
2014-10-01 12:14:38 +02:00
void SendPlayerListUpdateDisplayName ( const cPlayer & a_Player , const AString & a_CustomName );
2014-09-18 18:50:17 +02:00
void SendPlayerListUpdateGameMode ( const cPlayer & a_Player );
void SendPlayerListUpdatePing ( const cPlayer & a_Player );
void SendPlayerMaxSpeed ( void ); ///< Informs the client of the maximum player speed (1.6.1+)
void SendPlayerMoveLook ( void );
void SendPlayerPosition ( void );
void SendPlayerSpawn ( const cPlayer & a_Player );
void SendPluginMessage ( const AString & a_Channel , const AString & a_Message ); // Exported in ManualBindings.cpp
void SendRemoveEntityEffect ( const cEntity & a_Entity , int a_EffectID );
2015-04-08 00:41:19 +10:00
void SendResetTitle ( void );
2014-09-18 18:50:17 +02:00
void SendRespawn ( eDimension a_Dimension , bool a_ShouldIgnoreDimensionChecks = false );
void SendScoreUpdate ( const AString & a_Objective , const AString & a_Player , cObjective :: Score a_Score , Byte a_Mode );
2014-10-01 12:14:38 +02:00
void SendScoreboardObjective ( const AString & a_Name , const AString & a_DisplayName , Byte a_Mode );
2015-04-08 00:41:19 +10:00
void SendSetSubTitle ( const cCompositeChat & a_SubTitle );
void SendSetRawSubTitle ( const AString & a_SubTitle );
void SendSetTitle ( const cCompositeChat & a_Title );
void SendSetRawTitle ( const AString & a_Title );
2014-09-18 18:50:17 +02:00
void SendSoundEffect ( const AString & a_SoundName , double a_X , double a_Y , double a_Z , float a_Volume , float a_Pitch ); // tolua_export
2015-11-23 23:39:19 +00:00
void SendSoundParticleEffect ( const EffectID a_EffectID , int a_SrcX , int a_SrcY , int a_SrcZ , int a_Data );
2014-09-18 18:50:17 +02:00
void SendSpawnFallingBlock ( const cFallingBlock & a_FallingBlock );
void SendSpawnMob ( const cMonster & a_Mob );
void SendSpawnObject ( const cEntity & a_Entity , char a_ObjectType , int a_ObjectData , Byte a_Yaw , Byte a_Pitch );
void SendSpawnVehicle ( const cEntity & a_Vehicle , char a_VehicleType , char a_VehicleSubType = 0 );
void SendStatistics ( const cStatManager & a_Manager );
void SendTabCompletionResults ( const AStringVector & a_Results );
void SendTeleportEntity ( const cEntity & a_Entity );
void SendThunderbolt ( int a_BlockX , int a_BlockY , int a_BlockZ );
2015-04-08 00:41:19 +10:00
void SendTitleTimes ( int a_FadeInTicks , int a_DisplayTicks , int a_FadeOutTicks );
2014-09-18 18:50:17 +02:00
void SendTimeUpdate ( Int64 a_WorldAge , Int64 a_TimeOfDay , bool a_DoDaylightCycle ); // tolua_export
void SendUnloadChunk ( int a_ChunkX , int a_ChunkZ );
void SendUpdateBlockEntity ( cBlockEntity & a_BlockEntity );
void SendUpdateSign ( int a_BlockX , int a_BlockY , int a_BlockZ , const AString & a_Line1 , const AString & a_Line2 , const AString & a_Line3 , const AString & a_Line4 );
void SendUseBed ( const cEntity & a_Entity , int a_BlockX , int a_BlockY , int a_BlockZ );
void SendWeather ( eWeather a_Weather );
void SendWholeInventory ( const cWindow & a_Window );
void SendWindowClose ( const cWindow & a_Window );
void SendWindowOpen ( const cWindow & a_Window );
2014-10-03 21:32:41 +01:00
void SendWindowProperty ( const cWindow & a_Window , short a_Property , short a_Value );
2012-06-14 13:06:06 +00:00
2014-02-20 23:24:39 +01:00
// tolua_begin
const AString & GetUsername ( void ) const ;
2014-07-21 15:19:48 +02:00
void SetUsername ( const AString & a_Username );
2016-02-05 23:45:45 +02:00
2014-10-20 18:59:40 +01:00
inline short GetPing ( void ) const { return static_cast < short > ( std :: chrono :: duration_cast < std :: chrono :: milliseconds > ( m_Ping ). count ()); }
2016-02-05 23:45:45 +02:00
2014-11-14 22:53:12 +01:00
/** Sets the maximal view distance. */
2014-02-20 23:24:39 +01:00
void SetViewDistance ( int a_ViewDistance );
2014-11-14 22:53:12 +01:00
/** Returns the view distance that the player currently have. */
2014-11-15 22:26:54 +01:00
int GetViewDistance ( void ) const { return m_CurrentViewDistance ; }
2014-11-14 22:53:12 +01:00
2014-11-15 14:27:50 +01:00
/** Returns the view distance that the player request, not the used view distance. */
2014-11-15 15:33:42 +01:00
int GetRequestedViewDistance ( void ) const { return m_RequestedViewDistance ; }
2014-11-14 22:53:12 +01:00
2014-02-20 23:24:39 +01:00
void SetLocale ( AString & a_Locale ) { m_Locale = a_Locale ; }
AString GetLocale ( void ) const { return m_Locale ; }
2012-06-14 13:06:06 +00:00
2014-02-20 23:24:39 +01:00
int GetUniqueID ( void ) const { return m_UniqueID ; }
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
bool HasPluginChannel ( const AString & a_PluginChannel );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called by the protocol when it receives the MC|Brand plugin message. Also callable by plugins.
Simply stores the string value. */
void SetClientBrand ( const AString & a_ClientBrand ) { m_ClientBrand = a_ClientBrand ; }
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Returns the client brand received in the MC|Brand plugin message or set by a plugin. */
const AString & GetClientBrand ( void ) const { return m_ClientBrand ; }
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
// tolua_end
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) */
2014-08-28 11:36:35 +02:00
bool WantsSendChunk ( int a_ChunkX , int a_ChunkZ );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) */
2012-06-14 13:06:06 +00:00
void AddWantedChunk ( int a_ChunkX , int a_ChunkZ );
2016-02-05 23:45:45 +02:00
2012-08-27 17:31:16 +00:00
// Calls that cProtocol descendants use to report state:
void PacketBufferFull ( void );
2013-12-12 23:05:23 +01:00
void PacketUnknown ( UInt32 a_PacketType );
2015-01-18 22:43:35 +01:00
void PacketError ( UInt32 a_PacketType );
2012-06-14 13:06:06 +00:00
2012-08-27 17:31:16 +00:00
// Calls that cProtocol descendants use for handling packets:
2015-01-18 22:43:35 +01:00
void HandleAnimation ( int a_Animation );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called when the protocol receives a MC|ItemName plugin message, indicating that the player named
an item in the anvil UI. */
void HandleAnvilItemName ( const AString & a_ItemName );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called when the protocol receives a MC|Beacon plugin message, indicating that the player set an effect
in the beacon UI. */
void HandleBeaconSelection ( int a_PrimaryEffect , int a_SecondaryEffect );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called when the protocol detects a chat packet. */
void HandleChat ( const AString & a_Message );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new
command in the command block UI, for a block-based commandblock. */
void HandleCommandBlockBlockChange ( int a_BlockX , int a_BlockY , int a_BlockZ , const AString & a_NewCommand );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new
command in the command block UI, for an entity-based commandblock (minecart?). */
2015-03-21 13:00:20 +01:00
void HandleCommandBlockEntityChange ( UInt32 a_EntityID , const AString & a_NewCommand );
2016-02-05 23:45:45 +02:00
2015-03-21 13:00:20 +01:00
/** Called when the client clicks the creative inventory window.
a_ClickAction specifies whether the click was inside the window or not (caLeftClick or caLeftClickOutside). */
void HandleCreativeInventory ( Int16 a_SlotNum , const cItem & a_HeldItem , eClickAction a_ClickAction );
2015-01-24 20:17:00 +01:00
/** Called when the player enchants an Item in the Enchanting table UI. */
2015-03-21 13:00:20 +01:00
void HandleEnchantItem ( UInt8 a_WindowID , UInt8 a_Enchantment );
2015-01-24 20:17:00 +01:00
2015-03-21 13:00:20 +01:00
void HandleEntityCrouch ( UInt32 a_EntityID , bool a_IsCrouching );
void HandleEntityLeaveBed ( UInt32 a_EntityID );
void HandleEntitySprinting ( UInt32 a_EntityID , bool a_IsSprinting );
2016-02-05 23:45:45 +02:00
2014-12-11 14:34:09 +01:00
/** Kicks the client if the same username is already logged in.
Returns false if the client has been kicked, true otherwise. */
2014-12-08 00:45:29 -08:00
bool CheckMultiLogin ( const AString & a_Username );
2016-02-05 23:45:45 +02:00
2014-01-13 20:32:15 +01:00
/** Called when the protocol handshake has been received (for protocol versions that support it;
otherwise the first instant when a username is received).
Returns true if the player is to be let in, false if they were disconnected
*/
2013-08-01 09:46:01 +02:00
bool HandleHandshake ( const AString & a_Username );
2016-02-05 23:45:45 +02:00
2015-08-05 01:24:59 +03:00
void HandleKeepAlive ( UInt32 a_KeepAliveID );
2015-03-21 15:40:56 +01:00
void HandleLeftClick ( int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace , UInt8 a_Status );
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** Called when the protocol receives a MC|TrSel packet, indicating that the player used a trade in
the NPC UI. */
void HandleNPCTrade ( int a_SlotNum );
2016-02-05 23:45:45 +02:00
2013-08-01 09:46:01 +02:00
void HandlePing ( void );
2013-12-15 15:11:59 +01:00
void HandlePlayerAbilities ( bool a_CanFly , bool a_IsFlying , float FlyingSpeed , float WalkingSpeed );
2012-08-27 17:31:16 +00:00
void HandlePlayerLook ( float a_Rotation , float a_Pitch , bool a_IsOnGround );
2014-05-26 16:38:14 +02:00
void HandlePlayerMoveLook ( double a_PosX , double a_PosY , double a_PosZ , double a_Stance , float a_Rotation , float a_Pitch , bool a_IsOnGround ); // While m_bPositionConfirmed (normal gameplay)
2015-07-21 21:25:37 +01:00
/** Verifies and sets player position, performing relevant checks
Calls relevant methods to process movement related statistics
Requires state of previous position and on-ground status, so must be called when these are still intact
*/
void HandlePlayerPos ( double a_PosX , double a_PosY , double a_PosZ , double a_Stance , bool a_IsOnGround );
2014-01-07 17:47:05 +01:00
void HandlePluginMessage ( const AString & a_Channel , const AString & a_Message );
2013-08-01 09:46:01 +02:00
void HandleRespawn ( void );
2014-02-04 10:59:05 -08:00
void HandleRightClick ( int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace , int a_CursorX , int a_CursorY , int a_CursorZ , const cItem & a_HeldItem );
2015-03-21 13:00:20 +01:00
void HandleSlotSelected ( Int16 a_SlotNum );
2013-09-06 00:04:49 +02:00
void HandleSteerVehicle ( float Forward , float Sideways );
2013-08-01 09:46:01 +02:00
void HandleTabCompletion ( const AString & a_Text );
2012-08-27 17:31:16 +00:00
void HandleUpdateSign (
2014-07-17 16:33:09 +02:00
int a_BlockX , int a_BlockY , int a_BlockZ ,
const AString & a_Line1 , const AString & a_Line2 ,
2012-08-27 17:31:16 +00:00
const AString & a_Line3 , const AString & a_Line4
);
2013-07-05 21:11:06 +00:00
void HandleUnmount ( void );
2015-03-21 13:00:20 +01:00
void HandleUseEntity ( UInt32 a_TargetEntityID , bool a_IsLeftClick );
void HandleWindowClick ( UInt8 a_WindowID , Int16 a_SlotNum , eClickAction a_ClickAction , const cItem & a_HeldItem );
void HandleWindowClose ( UInt8 a_WindowID );
2013-08-01 09:46:01 +02:00
2012-08-30 08:19:19 +00:00
/** Called when the protocol has finished logging the user in.
Return true to allow the user in; false to kick them.
*/
2015-07-29 09:04:03 -06:00
bool HandleLogin ( UInt32 a_ProtocolVersion , const AString & a_Username );
2016-02-05 23:45:45 +02:00
2014-04-04 10:13:25 +02:00
void SendData ( const char * a_Data , size_t a_Size );
2016-02-05 23:45:45 +02:00
2014-06-06 22:31:16 +02:00
/** Called when the player moves into a different world.
2014-06-08 21:58:08 +02:00
Sends an UnloadChunk packet for each loaded chunk and resets the streamed chunks. */
void RemoveFromWorld ( void );
2016-02-05 23:45:45 +02:00
2014-10-05 20:19:21 +02:00
/** Called by the protocol recognizer when the protocol version is known. */
void SetProtocolVersion ( UInt32 a_ProtocolVersion ) { m_ProtocolVersion = a_ProtocolVersion ; }
/** Returns the protocol version number of the protocol that the client is talking. Returns zero if the protocol version is not (yet) known. */
UInt32 GetProtocolVersion ( void ) const { return m_ProtocolVersion ; } // tolua_export
2016-02-05 23:45:45 +02:00
2014-03-31 20:34:11 +01:00
private :
2015-01-24 20:17:00 +01:00
friend class cServer ; // Needs access to SetSelf()
2014-02-20 23:24:39 +01:00
/** The type used for storing the names of registered plugin channels. */
typedef std :: set < AString > cChannels ;
2014-11-15 22:26:54 +01:00
/** The actual view distance used, the minimum of client's requested view distance and world's max view distance. */
int m_CurrentViewDistance ;
2014-11-14 22:53:12 +01:00
2014-11-15 15:33:42 +01:00
/** The requested view distance from the player. It isn't clamped with 1 and the max view distance of the world. */
int m_RequestedViewDistance ;
2014-11-14 22:53:12 +01:00
2012-09-25 08:23:19 +00:00
AString m_IPString ;
2012-06-14 13:06:06 +00:00
AString m_Username ;
AString m_Password ;
2014-07-16 00:03:47 +01:00
Json :: Value m_Properties ;
2012-06-14 13:06:06 +00:00
2015-06-10 15:16:05 +01:00
cCriticalSection m_CSChunkLists ;
2015-10-05 16:20:07 +01:00
std :: unordered_set < cChunkCoords , cChunkCoordsHash > m_LoadedChunks ; // Chunks that the player belongs to
2015-06-10 15:16:05 +01:00
std :: unordered_set < cChunkCoords , cChunkCoordsHash > m_ChunksToSend ; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them)
cChunkCoordsList m_SentChunks ; // Chunks that are currently sent to the client
2012-06-14 13:06:06 +00:00
2012-08-27 17:31:16 +00:00
cProtocol * m_Protocol ;
2015-01-24 20:17:00 +01:00
/** Protects m_IncomingData against multithreaded access. */
2013-08-13 22:45:29 +02:00
cCriticalSection m_CSIncomingData ;
2015-01-24 20:17:00 +01:00
/** Queue for the incoming data received on the link until it is processed in Tick().
Protected by m_CSIncomingData. */
AString m_IncomingData ;
2015-01-26 14:49:51 +01:00
/** Protects m_OutgoingData against multithreaded access. */
2012-08-27 17:31:16 +00:00
cCriticalSection m_CSOutgoingData ;
2012-06-14 13:06:06 +00:00
2015-01-26 14:49:51 +01:00
/** Buffer for storing outgoing data from any thread; will get sent in Tick() (to prevent deadlocks).
Protected by m_CSOutgoingData. */
AString m_OutgoingData ;
2012-06-14 13:06:06 +00:00
Vector3d m_ConfirmPosition ;
cPlayer * m_Player ;
2016-02-05 23:45:45 +02:00
2015-05-09 09:25:09 +02:00
bool m_HasSentDC ; ///< True if a Disconnect packet has been sent in either direction
2012-06-14 13:06:06 +00:00
// Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk
int m_LastStreamedChunkX ;
int m_LastStreamedChunkZ ;
2015-01-24 20:17:00 +01:00
/** Number of ticks since the last network packet was received (increased in Tick(), reset in OnReceivedData()) */
2015-12-30 15:31:42 +01:00
std :: atomic < int > m_TicksSinceLastPacket ;
2016-02-05 23:45:45 +02:00
2014-12-07 15:46:27 +01:00
/** Duration of the last completed client ping. */
2014-10-20 18:59:40 +01:00
std :: chrono :: steady_clock :: duration m_Ping ;
2014-12-07 15:46:27 +01:00
/** ID of the last ping request sent to the client. */
2015-08-05 01:24:59 +03:00
UInt32 m_PingID ;
2014-12-07 15:46:27 +01:00
/** Time of the last ping request sent to the client. */
2014-10-20 18:59:40 +01:00
std :: chrono :: steady_clock :: time_point m_PingStartTime ;
2014-12-07 15:46:27 +01:00
2012-09-25 09:54:36 +00:00
// Values required for block dig animation
2013-01-12 04:46:01 +00:00
int m_BlockDigAnimStage ; // Current stage of the animation; -1 if not digging
2012-09-25 09:54:36 +00:00
int m_BlockDigAnimSpeed ; // Current speed of the animation (units ???)
2013-01-12 04:46:01 +00:00
int m_BlockDigAnimX ;
int m_BlockDigAnimY ;
int m_BlockDigAnimZ ;
2012-06-14 13:06:06 +00:00
2015-05-09 09:25:09 +02:00
// To avoid dig / aim bug in the client, store the last position given in a DIG_START packet and compare to that when processing the DIG_FINISH packet:
2013-01-12 04:46:01 +00:00
bool m_HasStartedDigging ;
int m_LastDigBlockX ;
int m_LastDigBlockY ;
int m_LastDigBlockZ ;
2012-11-12 11:10:01 +00:00
2012-06-14 13:06:06 +00:00
enum eState
{
2013-08-13 22:45:29 +02:00
csConnected , ///< The client has just connected, waiting for their handshake / login
csAuthenticating , ///< The client has logged in, waiting for external authentication
csAuthenticated , ///< The client has been authenticated, will start streaming chunks in the next tick
csDownloadingWorld , ///< The client is waiting for chunks, we're waiting for the loader to provide and send them
2014-07-17 16:33:09 +02:00
csConfirmingPos , ///< The client has been sent the position packet, waiting for them to repeat the position back
2013-08-13 22:45:29 +02:00
csPlaying , ///< Normal gameplay
csDestroying , ///< The client is being destroyed, don't queue any more packets / don't add to chunks
csDestroyed , ///< The client has been destroyed, the destructor is to be called from the owner thread
2016-02-05 23:45:45 +02:00
2012-11-11 14:00:58 +00:00
// TODO: Add Kicking here as well
2012-06-14 13:06:06 +00:00
} ;
2016-02-05 23:45:45 +02:00
2015-06-27 12:10:24 +01:00
std :: atomic < eState > m_State ;
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** m_State needs to be locked in the Destroy() function so that the destruction code doesn't run twice on two different threads */
2013-08-13 22:45:29 +02:00
cCriticalSection m_CSDestroyingState ;
2012-06-14 13:06:06 +00:00
2014-02-20 23:24:39 +01:00
/** If set to true during csDownloadingWorld, the tick thread calls CheckIfWorldDownloaded() */
2012-08-31 16:26:03 +00:00
bool m_ShouldCheckDownloaded ;
2012-06-14 13:06:06 +00:00
2014-02-04 23:40:58 +00:00
/** Number of explosions sent this tick */
int m_NumExplosionsThisTick ;
2014-03-01 21:24:36 +00:00
/** Number of place or break interactions this tick */
int m_NumBlockChangeInteractionsThisTick ;
2016-02-05 23:45:45 +02:00
2013-07-28 19:15:03 +02:00
static int s_ClientCount ;
2016-02-05 23:45:45 +02:00
2014-07-30 13:52:51 +02:00
/** ID used for identification during authenticating. Assigned sequentially for each new instance. */
2013-07-28 19:15:03 +02:00
int m_UniqueID ;
2016-02-05 23:45:45 +02:00
2014-07-30 13:52:51 +02:00
/** Contains the UUID used by Mojang to identify the player's account. Short UUID stored here (without dashes) */
2014-04-13 13:04:56 +02:00
AString m_UUID ;
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Set to true when the chunk where the player is is sent to the client. Used for spawning the player */
2013-09-08 18:36:06 +02:00
bool m_HasSentPlayerChunk ;
2014-02-16 13:26:07 +01:00
2014-02-20 23:24:39 +01:00
/** Client Settings */
2014-02-16 13:26:07 +01:00
AString m_Locale ;
2014-11-15 15:16:52 +01:00
2014-11-15 22:36:31 +01:00
/** The positions from the last sign that the player placed. It's needed to verify the sign text change. */
Vector3i m_LastPlacedSign ;
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** The plugin channels that the client has registered. */
cChannels m_PluginChannels ;
2016-02-05 23:45:45 +02:00
2014-09-30 13:33:57 +02:00
/** The brand identification of the client, as received in the MC|Brand plugin message or set from a plugin. */
AString m_ClientBrand ;
2013-06-18 19:32:31 +00:00
2014-10-05 20:19:21 +02:00
/** The version of the protocol that the client is talking, or 0 if unknown. */
UInt32 m_ProtocolVersion ;
2015-01-24 20:17:00 +01:00
/** The link that is used for network communication.
m_CSOutgoingData is used to synchronize access for sending data. */
cTCPLinkPtr m_Link ;
/** Shared pointer to self, so that this instance can keep itself alive when needed. */
cClientHandlePtr m_Self ;
2013-06-18 19:32:31 +00:00
2014-02-20 23:24:39 +01:00
/** Returns true if the rate block interactions is within a reasonable limit (bot protection) */
2012-06-14 13:06:06 +00:00
bool CheckBlockInteractionsRate ( void );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Adds a single chunk to be streamed to the client; used by StreamChunks() */
2014-10-06 21:27:53 +02:00
void StreamChunk ( int a_ChunkX , int a_ChunkZ , cChunkSender :: eChunkPriority a_Priority );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Handles the DIG_STARTED dig packet: */
2014-02-04 10:59:05 -08:00
void HandleBlockDigStarted ( int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace , BLOCKTYPE a_OldBlock , NIBBLETYPE a_OldMeta );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Handles the DIG_FINISHED dig packet: */
2014-02-04 10:59:05 -08:00
void HandleBlockDigFinished ( int a_BlockX , int a_BlockY , int a_BlockZ , eBlockFace a_BlockFace , BLOCKTYPE a_OldBlock , NIBBLETYPE a_OldMeta );
2014-01-18 19:58:46 +02:00
2014-05-11 11:56:15 +02:00
/** The clients will receive a finished dig animation */
void FinishDigAnimation ();
2014-05-09 23:10:02 +02:00
2014-02-20 23:24:39 +01:00
/** Converts the protocol-formatted channel list (NUL-separated) into a proper string vector. */
AStringVector BreakApartPluginChannels ( const AString & a_PluginChannels );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Adds all of the channels to the list of current plugin channels. Handles duplicates gracefully. */
void RegisterPluginChannels ( const AStringVector & a_ChannelList );
2016-02-05 23:45:45 +02:00
2014-02-20 23:24:39 +01:00
/** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */
void UnregisterPluginChannels ( const AStringVector & a_ChannelList );
2014-07-30 21:59:35 +02:00
2015-01-24 20:17:00 +01:00
/** Called when the network socket has been closed. */
void SocketClosed ( void );
2012-06-14 13:06:06 +00:00
2015-01-24 20:17:00 +01:00
/** Called right after the instance is created to store its SharedPtr inside. */
void SetSelf ( cClientHandlePtr a_Self );
2012-06-14 13:06:06 +00:00
2015-01-24 20:17:00 +01:00
// cTCPLink::cCallbacks overrides:
virtual void OnLinkCreated ( cTCPLinkPtr a_Link ) override ;
virtual void OnReceivedData ( const char * a_Data , size_t a_Length ) override ;
virtual void OnRemoteClosed ( void ) override ;
virtual void OnError ( int a_ErrorCode , const AString & a_ErrorMsg ) override ;
}; // tolua_export
2012-06-14 13:06:06 +00:00