From 25e4f15488c1f56c1571f4aefd216830e62ad52b Mon Sep 17 00:00:00 2001 From: sweetgiorni Date: Tue, 3 Jan 2017 10:57:31 -0800 Subject: Custom Disconnect Message Adds a m_ShutdownMessage option to the settings. When the stop command is issued, players are kicked with said message before the server shuts down. --- src/Root.cpp | 16 ++++++++++++++++ src/Server.cpp | 1 + src/Server.h | 3 +++ 3 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index 3d3930975..90e5cb9db 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -332,6 +332,22 @@ void cRoot::Start(std::unique_ptr a_OverridesRepo) void cRoot::StopServer() { + // Kick all players from the server with custom disconnect message + class cPlayerCallback : public cPlayerListCallback + { + AString m_ShutdownMessage; + virtual bool Item(cPlayer * a_Player) + { + a_Player->GetClientHandlePtr()->Kick(m_ShutdownMessage); + return false; + } + public: + cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) {} + }PlayerCallback((m_Server->GetShutdownMessage())); + + cRoot::Get()->ForEachPlayer(PlayerCallback); + // What's a better way to do this? + std::this_thread::sleep_for(std::chrono::seconds(1)); m_TerminateEventRaised = true; m_StopEvent.Set(); m_InputThreadRunFlag.clear(); diff --git a/src/Server.cpp b/src/Server.cpp index ba469bd3e..95e0b535b 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -190,6 +190,7 @@ void cServer::PlayerDestroying(const cPlayer * a_Player) bool cServer::InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth) { m_Description = a_Settings.GetValueSet("Server", "Description", "Cuberite - in C++!"); + m_ShutdownMessage = a_Settings.GetValueSet("Server", "ShutdownMessage", "Server shutdown"); m_MaxPlayers = a_Settings.GetValueSetI("Server", "MaxPlayers", 100); m_bIsHardcore = a_Settings.GetValueSetB("Server", "HardcoreEnabled", false); m_bAllowMultiLogin = a_Settings.GetValueSetB("Server", "AllowMultiLogin", false); diff --git a/src/Server.h b/src/Server.h index 600e7ca97..74f9581ae 100644 --- a/src/Server.h +++ b/src/Server.h @@ -64,6 +64,8 @@ public: const AString & GetDescription(void) const {return m_Description; } + const AString & GetShutdownMessage(void) const { return m_ShutdownMessage; } + // Player counts: int GetMaxPlayers(void) const { return m_MaxPlayers; } int GetNumPlayers(void) const; @@ -204,6 +206,7 @@ private: cRCONServer m_RCONServer; AString m_Description; + AString m_ShutdownMessage; AString m_FaviconData; int m_MaxPlayers; bool m_bIsHardcore; -- cgit v1.2.3 From 78b6d54bf86c892827fa0a470375ba50318a0bd0 Mon Sep 17 00:00:00 2001 From: sweetgiorni Date: Tue, 3 Jan 2017 12:18:53 -0800 Subject: Api Documentation Added API documentation for GetShutdownMessage. Style fix in Root.cpp --- src/Root.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index 90e5cb9db..a5567dc9b 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -343,7 +343,7 @@ void cRoot::StopServer() } public: cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) {} - }PlayerCallback((m_Server->GetShutdownMessage())); + } PlayerCallback((m_Server->GetShutdownMessage())); cRoot::Get()->ForEachPlayer(PlayerCallback); // What's a better way to do this? -- cgit v1.2.3 From 0718d82e1a5a6fdfe9346f801fa008f2b37cf69d Mon Sep 17 00:00:00 2001 From: sweetgiorni Date: Tue, 3 Jan 2017 12:26:58 -0800 Subject: Player check Checks if there are any players connected to the server before running PlayerCallback and waiting 1 second. --- src/Root.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index a5567dc9b..80366e5c1 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -343,11 +343,14 @@ void cRoot::StopServer() } public: cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) {} - } PlayerCallback((m_Server->GetShutdownMessage())); + }; - cRoot::Get()->ForEachPlayer(PlayerCallback); - // What's a better way to do this? - std::this_thread::sleep_for(std::chrono::seconds(1)); + if (m_Server->GetNumPlayers()) + { + cPlayerCallback PlayerCallback((m_Server->GetShutdownMessage())); + cRoot::Get()->ForEachPlayer(PlayerCallback); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } m_TerminateEventRaised = true; m_StopEvent.Set(); m_InputThreadRunFlag.clear(); -- cgit v1.2.3 From 28cc26c54ca09ed9ceb2ed2df53dc323f0be405c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 3 Jan 2017 12:19:29 -0800 Subject: Track skin part and main hand preferences (#3498) --- src/Defines.h | 36 ++++++++++++++++++++++++++++++++++++ src/Entities/Player.cpp | 24 +++++++++++++++++++++++- src/Entities/Player.h | 13 +++++++++++++ src/Protocol/Protocol_1_10.cpp | 8 ++++++++ src/Protocol/Protocol_1_8.cpp | 20 +++++++++++++++++--- src/Protocol/Protocol_1_9.cpp | 16 +++++++++++++--- 6 files changed, 110 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Defines.h b/src/Defines.h index f8af22ef2..a1de94897 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -203,6 +203,42 @@ enum eMobHeadRotation +enum eHand +{ + hMain = 0, + hOff = 1, +} ; + + + + + +enum eMainHand +{ + mhLeft = 0, + mhRight = 1, +} ; + + + + + +enum eSkinPart +{ + spCape = 0x01, + spJacket = 0x02, + spLeftSleeve = 0x04, + spRightSleeve = 0x08, + spLeftPants = 0x10, + spRightPants = 0x20, + spHat = 0x40, + spMask = 0x7F, +}; + + + + + inline const char * ClickActionToString(int a_ClickAction) { switch (a_ClickAction) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index f3ea45cf4..9fba0d015 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -90,7 +90,9 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) : m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL), m_bIsTeleporting(false), m_UUID((a_Client != nullptr) ? a_Client->GetUUID() : ""), - m_CustomName("") + m_CustomName(""), + m_SkinParts(0), + m_MainHand(mhRight) { ASSERT(a_PlayerName.length() <= 16); // Otherwise this player could crash many clients... @@ -2632,6 +2634,26 @@ bool cPlayer::PlaceBlocks(const sSetBlockVector & a_Blocks) +void cPlayer::SetSkinParts(int a_Parts) +{ + m_SkinParts = a_Parts & spMask; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle.get()); +} + + + + + +void cPlayer::SetMainHand(eMainHand a_Hand) +{ + m_MainHand = a_Hand; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle.get()); +} + + + + + void cPlayer::AttachTo(cEntity * a_AttachTo) { // Different attach, if this is a spectator diff --git a/src/Entities/Player.h b/src/Entities/Player.h index dab814692..b592913bd 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -499,6 +499,13 @@ public: The blocks in range (a_BlockX - a_Range, a_BlockX + a_Range) are sent (NY-metric). */ void SendBlocksAround(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Range = 1); + bool HasSkinPart(eSkinPart a_Part) const { return (m_SkinParts & a_Part) != 0; } + int GetSkinParts(void) const { return m_SkinParts; } + void SetSkinParts(int a_Parts); + + eMainHand GetMainHand(void) const { return m_MainHand; } + void SetMainHand(eMainHand a_Hand); + // tolua_end /** Calls the block placement hooks and places the blocks in the world. @@ -682,6 +689,12 @@ protected: AString m_CustomName; + /** Displayed skin part bit mask */ + int m_SkinParts; + + /** The main hand of the player */ + eMainHand m_MainHand; + /** Sets the speed and sends it to the client, so that they are forced to move so. */ virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; diff --git a/src/Protocol/Protocol_1_10.cpp b/src/Protocol/Protocol_1_10.cpp index c0d9d921f..1cd7153a7 100644 --- a/src/Protocol/Protocol_1_10.cpp +++ b/src/Protocol/Protocol_1_10.cpp @@ -400,6 +400,14 @@ void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Pkt.WriteBEUInt8(LIVING_HEALTH); a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT); a_Pkt.WriteBEFloat(static_cast(Player.GetHealth())); + + a_Pkt.WriteBEUInt8(PLAYER_DISPLAYED_SKIN_PARTS); + a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); + a_Pkt.WriteBEUInt8(static_cast(Player.GetSkinParts())); + + a_Pkt.WriteBEUInt8(PLAYER_MAIN_HAND); + a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); + a_Pkt.WriteBEUInt8(static_cast(Player.GetMainHand())); break; } case cEntity::etPickup: diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index bbeb3ae8b..2e7902303 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -2311,11 +2311,12 @@ void cProtocol_1_8_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ViewDistance); HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags); HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinFlags); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts); m_Client->SetLocale(Locale); m_Client->SetViewDistance(ViewDistance); - // TODO: Handle other values + m_Client->GetPlayer()->SetSkinParts(SkinParts); + // TODO: Handle chat flags and chat colors } @@ -3234,7 +3235,20 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a switch (a_Entity.GetEntityType()) { - case cEntity::etPlayer: break; // TODO? + case cEntity::etPlayer: + { + auto & Player = reinterpret_cast(a_Entity); + + // Player health (not handled since players aren't monsters) + a_Pkt.WriteBEUInt8(0x66); + a_Pkt.WriteBEFloat(static_cast(Player.GetHealth())); + + // Skin flags + a_Pkt.WriteBEUInt8(0x0A); + a_Pkt.WriteBEUInt8(static_cast(Player.GetSkinParts())); + + break; + } case cEntity::etPickup: { a_Pkt.WriteBEUInt8((5 << 5) | 10); // Slot(5) + index 10 diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 680675ca3..69b8deb55 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -2355,12 +2355,14 @@ void cProtocol_1_9_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ViewDistance); HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags); HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); - HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinFlags); + HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts); HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, MainHand); m_Client->SetLocale(Locale); m_Client->SetViewDistance(ViewDistance); - // TODO: Handle other values + m_Client->GetPlayer()->SetSkinParts(SkinParts); + m_Client->GetPlayer()->SetMainHand(static_cast(MainHand)); + // TODO: Handle chat flags and chat colors } @@ -3552,9 +3554,17 @@ void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING); a_Pkt.WriteString(Player.GetName()); - a_Pkt.WriteBEUInt8(6); // Start metadata - Index 6: Health + a_Pkt.WriteBEUInt8(6); // Index 6: Health a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT); a_Pkt.WriteBEFloat(static_cast(Player.GetHealth())); + + a_Pkt.WriteBEUInt8(12); + a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); + a_Pkt.WriteBEUInt8(static_cast(Player.GetSkinParts())); + + a_Pkt.WriteBEUInt8(13); + a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); + a_Pkt.WriteBEUInt8(static_cast(Player.GetMainHand())); break; } case cEntity::etPickup: -- cgit v1.2.3 From ff1c0605db37bf989fc7e2c920c4852522793432 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 3 Jan 2017 21:20:01 +0100 Subject: TCPLink: call networking callbacks with LibEvent unlocked. (#3515) --- src/OSSupport/TCPLinkImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/OSSupport/TCPLinkImpl.cpp b/src/OSSupport/TCPLinkImpl.cpp index d55dc9da1..47be99a48 100644 --- a/src/OSSupport/TCPLinkImpl.cpp +++ b/src/OSSupport/TCPLinkImpl.cpp @@ -18,7 +18,7 @@ cTCPLinkImpl::cTCPLinkImpl(cTCPLink::cCallbacksPtr a_LinkCallbacks): super(a_LinkCallbacks), - m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE)), + m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)), m_LocalPort(0), m_RemotePort(0), m_ShouldShutdown(false) @@ -31,7 +31,7 @@ cTCPLinkImpl::cTCPLinkImpl(cTCPLink::cCallbacksPtr a_LinkCallbacks): cTCPLinkImpl::cTCPLinkImpl(evutil_socket_t a_Socket, cTCPLink::cCallbacksPtr a_LinkCallbacks, cServerHandleImplPtr a_Server, const sockaddr * a_Address, socklen_t a_AddrLen): super(a_LinkCallbacks), - m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), a_Socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE)), + m_BufferEvent(bufferevent_socket_new(cNetworkSingleton::Get().GetEventBase(), a_Socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS)), m_Server(a_Server), m_LocalPort(0), m_RemotePort(0), -- cgit v1.2.3 From 6522385897788df4682a1744b17815c0767c46f8 Mon Sep 17 00:00:00 2001 From: sweetgiorni Date: Tue, 3 Jan 2017 12:39:39 -0800 Subject: Disconnect sent flag added Truthiness no longer assumed --- src/Root.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index 80366e5c1..8390cac7b 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -339,16 +339,17 @@ void cRoot::StopServer() virtual bool Item(cPlayer * a_Player) { a_Player->GetClientHandlePtr()->Kick(m_ShutdownMessage); + m_HasSentDisconnect = true; return false; } public: - cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) {} - }; + bool m_HasSentDisconnect; + cPlayerCallback(AString a_ShutdownMessage) : m_ShutdownMessage(a_ShutdownMessage) { m_HasSentDisconnect = false; } + } PlayerCallback(m_Server->GetShutdownMessage()); - if (m_Server->GetNumPlayers()) + cRoot::Get()->ForEachPlayer(PlayerCallback); + if (PlayerCallback.m_HasSentDisconnect) { - cPlayerCallback PlayerCallback((m_Server->GetShutdownMessage())); - cRoot::Get()->ForEachPlayer(PlayerCallback); std::this_thread::sleep_for(std::chrono::seconds(1)); } m_TerminateEventRaised = true; -- cgit v1.2.3