cClientHandle manages the client-registered plugin channels.
Fixes #706.
This commit is contained in:
parent
ffc4691f48
commit
27e77a28fa
@ -542,19 +542,23 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
|
|||||||
|
|
||||||
void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString & a_Message)
|
void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString & a_Message)
|
||||||
{
|
{
|
||||||
if (a_Channel == "MC|AdvCdm") // Command block, set text, Client -> Server
|
if (a_Channel == "MC|AdvCdm")
|
||||||
{
|
{
|
||||||
const char* Data = a_Message.c_str();
|
// Command block, set text, Client -> Server
|
||||||
HandleCommandBlockMessage(Data, a_Message.size());
|
HandleCommandBlockMessage(a_Message.c_str(), a_Message.size());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else if (a_Channel == "MC|Brand") // Client <-> Server branding exchange
|
else if (a_Channel == "MC|Brand")
|
||||||
{
|
{
|
||||||
// We are custom,
|
// Client <-> Server branding exchange
|
||||||
// We are awesome,
|
|
||||||
// We are MCServer.
|
|
||||||
SendPluginMessage("MC|Brand", "MCServer");
|
SendPluginMessage("MC|Brand", "MCServer");
|
||||||
return;
|
}
|
||||||
|
else if (a_Channel == "REGISTER")
|
||||||
|
{
|
||||||
|
RegisterPluginChannels(BreakApartPluginChannels(a_Message));
|
||||||
|
}
|
||||||
|
else if (a_Channel == "UNREGISTER")
|
||||||
|
{
|
||||||
|
UnregisterPluginChannels(BreakApartPluginChannels(a_Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
cPluginManager::Get()->CallHookPluginMessage(*this, a_Channel, a_Message);
|
cPluginManager::Get()->CallHookPluginMessage(*this, a_Channel, a_Message);
|
||||||
@ -564,7 +568,61 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a_Length)
|
AStringVector cClientHandle::BreakApartPluginChannels(const AString & a_PluginChannels)
|
||||||
|
{
|
||||||
|
// Break the string on each NUL character.
|
||||||
|
// Note that StringSplit() doesn't work on this because NUL is a special char - string terminator
|
||||||
|
size_t len = a_PluginChannels.size();
|
||||||
|
size_t first = 0;
|
||||||
|
AStringVector res;
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (a_PluginChannels[i] != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i > first)
|
||||||
|
{
|
||||||
|
res.push_back(a_PluginChannels.substr(first, i - first));
|
||||||
|
}
|
||||||
|
first = i + 1;
|
||||||
|
} // for i - a_PluginChannels[]
|
||||||
|
if (first < len)
|
||||||
|
{
|
||||||
|
res.push_back(a_PluginChannels.substr(first, len - first));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::RegisterPluginChannels(const AStringVector & a_ChannelList)
|
||||||
|
{
|
||||||
|
for (AStringVector::const_iterator itr = a_ChannelList.begin(), end = a_ChannelList.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
m_PluginChannels.insert(*itr);
|
||||||
|
} // for itr - a_ChannelList[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::UnregisterPluginChannels(const AStringVector & a_ChannelList)
|
||||||
|
{
|
||||||
|
for (AStringVector::const_iterator itr = a_ChannelList.begin(), end = a_ChannelList.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
m_PluginChannels.erase(*itr);
|
||||||
|
} // for itr - a_ChannelList[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::HandleCommandBlockMessage(const char * a_Data, unsigned int a_Length)
|
||||||
{
|
{
|
||||||
if (a_Length < 14)
|
if (a_Length < 14)
|
||||||
{
|
{
|
||||||
@ -2463,6 +2521,15 @@ void cClientHandle::SetViewDistance(int a_ViewDistance)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cClientHandle::HasPluginChannel(const AString & a_PluginChannel)
|
||||||
|
{
|
||||||
|
return (m_PluginChannels.find(a_PluginChannel) != m_PluginChannels.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
if (m_State >= csDestroying)
|
if (m_State >= csDestroying)
|
||||||
|
@ -72,10 +72,10 @@ public:
|
|||||||
|
|
||||||
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
|
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
|
||||||
|
|
||||||
/// Called while the client is being ticked from the world via its cPlayer object
|
/** Called while the client is being ticked from the world via its cPlayer object */
|
||||||
void Tick(float a_Dt);
|
void Tick(float a_Dt);
|
||||||
|
|
||||||
/// Called while the client is being ticked from the cServer object
|
/** Called while the client is being ticked from the cServer object */
|
||||||
void ServerTick(float a_Dt);
|
void ServerTick(float a_Dt);
|
||||||
|
|
||||||
void Destroy(void);
|
void Destroy(void);
|
||||||
@ -150,23 +150,28 @@ public:
|
|||||||
void SendWindowOpen (const cWindow & a_Window);
|
void SendWindowOpen (const cWindow & a_Window);
|
||||||
void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value);
|
void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value);
|
||||||
|
|
||||||
const AString & GetUsername(void) const; // tolua_export
|
// tolua_begin
|
||||||
void SetUsername( const AString & a_Username ); // tolua_export
|
const AString & GetUsername(void) const;
|
||||||
|
void SetUsername( const AString & a_Username );
|
||||||
|
|
||||||
inline short GetPing(void) const { return m_Ping; } // tolua_export
|
inline short GetPing(void) const { return m_Ping; }
|
||||||
|
|
||||||
void SetViewDistance(int a_ViewDistance); // tolua_export
|
void SetViewDistance(int a_ViewDistance);
|
||||||
int GetViewDistance(void) const { return m_ViewDistance; } // tolua_export
|
int GetViewDistance(void) const { return m_ViewDistance; }
|
||||||
|
|
||||||
void SetLocale(AString & a_Locale) { m_Locale = a_Locale; } // tolua_export
|
void SetLocale(AString & a_Locale) { m_Locale = a_Locale; }
|
||||||
AString GetLocale(void) const { return m_Locale; } // tolua_export
|
AString GetLocale(void) const { return m_Locale; }
|
||||||
|
|
||||||
int GetUniqueID() const { return m_UniqueID; } // tolua_export
|
int GetUniqueID(void) const { return m_UniqueID; }
|
||||||
|
|
||||||
/// Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend)
|
bool HasPluginChannel(const AString & a_PluginChannel);
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
/** Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) */
|
||||||
bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
bool WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||||
|
|
||||||
/// Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend)
|
/** Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) */
|
||||||
void AddWantedChunk(int a_ChunkX, int a_ChunkZ);
|
void AddWantedChunk(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
// Calls that cProtocol descendants use to report state:
|
// Calls that cProtocol descendants use to report state:
|
||||||
@ -217,14 +222,17 @@ public:
|
|||||||
|
|
||||||
void SendData(const char * a_Data, int a_Size);
|
void SendData(const char * a_Data, int a_Size);
|
||||||
|
|
||||||
/// Called when the player moves into a different world; queues sreaming the new chunks
|
/** Called when the player moves into a different world; queues sreaming the new chunks */
|
||||||
void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket);
|
void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket);
|
||||||
|
|
||||||
/// Handles the block placing packet when it is a real block placement (not block-using, item-using or eating)
|
/** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */
|
||||||
void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler);
|
void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/** The type used for storing the names of registered plugin channels. */
|
||||||
|
typedef std::set<AString> cChannels;
|
||||||
|
|
||||||
int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 )
|
int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 )
|
||||||
|
|
||||||
static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation
|
static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation
|
||||||
@ -257,7 +265,7 @@ private:
|
|||||||
int m_LastStreamedChunkX;
|
int m_LastStreamedChunkX;
|
||||||
int m_LastStreamedChunkZ;
|
int m_LastStreamedChunkZ;
|
||||||
|
|
||||||
/// Seconds since the last packet data was received (updated in Tick(), reset in DataReceived())
|
/** Seconds since the last packet data was received (updated in Tick(), reset in DataReceived()) */
|
||||||
float m_TimeSinceLastPacket;
|
float m_TimeSinceLastPacket;
|
||||||
|
|
||||||
short m_Ping;
|
short m_Ping;
|
||||||
@ -279,7 +287,7 @@ private:
|
|||||||
int m_LastDigBlockY;
|
int m_LastDigBlockY;
|
||||||
int m_LastDigBlockZ;
|
int m_LastDigBlockZ;
|
||||||
|
|
||||||
/// Used while csDestroyedWaiting for counting the ticks until the connection is closed
|
/** Used while csDestroyedWaiting for counting the ticks until the connection is closed */
|
||||||
int m_TicksSinceDestruction;
|
int m_TicksSinceDestruction;
|
||||||
|
|
||||||
enum eState
|
enum eState
|
||||||
@ -299,10 +307,10 @@ private:
|
|||||||
|
|
||||||
eState m_State;
|
eState m_State;
|
||||||
|
|
||||||
/// m_State needs to be locked in the Destroy() function so that the destruction code doesn't run twice on two different threads
|
/** m_State needs to be locked in the Destroy() function so that the destruction code doesn't run twice on two different threads */
|
||||||
cCriticalSection m_CSDestroyingState;
|
cCriticalSection m_CSDestroyingState;
|
||||||
|
|
||||||
/// If set to true during csDownloadingWorld, the tick thread calls CheckIfWorldDownloaded()
|
/** If set to true during csDownloadingWorld, the tick thread calls CheckIfWorldDownloaded() */
|
||||||
bool m_ShouldCheckDownloaded;
|
bool m_ShouldCheckDownloaded;
|
||||||
|
|
||||||
/** Number of explosions sent this tick */
|
/** Number of explosions sent this tick */
|
||||||
@ -311,27 +319,39 @@ private:
|
|||||||
static int s_ClientCount;
|
static int s_ClientCount;
|
||||||
int m_UniqueID;
|
int m_UniqueID;
|
||||||
|
|
||||||
/// Set to true when the chunk where the player is is sent to the client. Used for spawning the player
|
/** Set to true when the chunk where the player is is sent to the client. Used for spawning the player */
|
||||||
bool m_HasSentPlayerChunk;
|
bool m_HasSentPlayerChunk;
|
||||||
|
|
||||||
/// Client Settings
|
/** Client Settings */
|
||||||
AString m_Locale;
|
AString m_Locale;
|
||||||
|
|
||||||
|
/** The plugin channels that the client has registered. */
|
||||||
|
cChannels m_PluginChannels;
|
||||||
|
|
||||||
|
|
||||||
/// Returns true if the rate block interactions is within a reasonable limit (bot protection)
|
/** Returns true if the rate block interactions is within a reasonable limit (bot protection) */
|
||||||
bool CheckBlockInteractionsRate(void);
|
bool CheckBlockInteractionsRate(void);
|
||||||
|
|
||||||
/// Adds a single chunk to be streamed to the client; used by StreamChunks()
|
/** Adds a single chunk to be streamed to the client; used by StreamChunks() */
|
||||||
void StreamChunk(int a_ChunkX, int a_ChunkZ);
|
void StreamChunk(int a_ChunkX, int a_ChunkZ);
|
||||||
|
|
||||||
/// Handles the DIG_STARTED dig packet:
|
/** Handles the DIG_STARTED dig packet: */
|
||||||
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
||||||
|
|
||||||
/// Handles the DIG_FINISHED dig packet:
|
/** Handles the DIG_FINISHED dig packet: */
|
||||||
void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
|
||||||
|
|
||||||
/// Handles the "MC|AdvCdm" plugin message
|
/** Converts the protocol-formatted channel list (NUL-separated) into a proper string vector. */
|
||||||
void HandleCommandBlockMessage(const char* a_Data, unsigned int a_Length);
|
AStringVector BreakApartPluginChannels(const AString & a_PluginChannels);
|
||||||
|
|
||||||
|
/** Adds all of the channels to the list of current plugin channels. Handles duplicates gracefully. */
|
||||||
|
void RegisterPluginChannels(const AStringVector & a_ChannelList);
|
||||||
|
|
||||||
|
/** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */
|
||||||
|
void UnregisterPluginChannels(const AStringVector & a_ChannelList);
|
||||||
|
|
||||||
|
/** Handles the "MC|AdvCdm" plugin message */
|
||||||
|
void HandleCommandBlockMessage(const char * a_Data, unsigned int a_Length);
|
||||||
|
|
||||||
// cSocketThreads::cCallback overrides:
|
// cSocketThreads::cCallback overrides:
|
||||||
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
|
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
|
||||||
|
Loading…
Reference in New Issue
Block a user