Implemented cCompositeChat.
This allows plugins to send composite chat messages, containing URLs, commands to run and cmdline suggestions. Fixes #678.master
parent
584f7bd806
commit
0f1f7583ae
|
@ -70,6 +70,7 @@ $cfile "../Generating/ChunkDesc.h"
|
||||||
$cfile "../CraftingRecipes.h"
|
$cfile "../CraftingRecipes.h"
|
||||||
$cfile "../UI/Window.h"
|
$cfile "../UI/Window.h"
|
||||||
$cfile "../Mobs/Monster.h"
|
$cfile "../Mobs/Monster.h"
|
||||||
|
$cfile "../CompositeChat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "MersenneTwister.h"
|
#include "MersenneTwister.h"
|
||||||
|
|
||||||
#include "Protocol/ProtocolRecognizer.h"
|
#include "Protocol/ProtocolRecognizer.h"
|
||||||
|
#include "CompositeChat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1729,7 +1730,7 @@ void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::SendChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const AString & a_AdditionalData)
|
void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData)
|
||||||
{
|
{
|
||||||
bool ShouldAppendChatPrefixes = true;
|
bool ShouldAppendChatPrefixes = true;
|
||||||
|
|
||||||
|
@ -1840,6 +1841,15 @@ void cClientHandle::SendChat(const AString & a_Message, ChatPrefixCodes a_ChatPr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::SendChat(const cCompositeChat & a_Message)
|
||||||
|
{
|
||||||
|
m_Protocol->SendChat(a_Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
||||||
{
|
{
|
||||||
ASSERT(m_Player != NULL);
|
ASSERT(m_Player != NULL);
|
||||||
|
|
|
@ -34,6 +34,7 @@ class cWindow;
|
||||||
class cFallingBlock;
|
class cFallingBlock;
|
||||||
class cItemHandler;
|
class cItemHandler;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
|
class cCompositeChat;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,7 +90,8 @@ public:
|
||||||
void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
|
void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
|
||||||
void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export
|
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 SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes);
|
||||||
void SendChat (const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const AString & a_AdditionalData = "");
|
void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
|
||||||
|
void SendChat (const cCompositeChat & a_Message);
|
||||||
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
|
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
|
||||||
void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player);
|
void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player);
|
||||||
void SendDestroyEntity (const cEntity & a_Entity);
|
void SendDestroyEntity (const cEntity & a_Entity);
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
|
||||||
|
// CompositeChat.cpp
|
||||||
|
|
||||||
|
// Implements the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd)
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "CompositeChat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat:
|
||||||
|
|
||||||
|
cCompositeChat::cCompositeChat(void) :
|
||||||
|
m_MessageType(mtCustom)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cCompositeChat::cCompositeChat(const AString & a_ParseText) :
|
||||||
|
m_MessageType(mtCustom)
|
||||||
|
{
|
||||||
|
ParseText(a_ParseText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cCompositeChat::~cCompositeChat()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::Clear(void)
|
||||||
|
{
|
||||||
|
for (cParts::iterator itr = m_Parts.begin(), end = m_Parts.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
delete *itr;
|
||||||
|
} // for itr - m_Parts[]
|
||||||
|
m_Parts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::AddTextPart(const AString & a_Message, const AString & a_Style)
|
||||||
|
{
|
||||||
|
m_Parts.push_back(new cTextPart(a_Message, a_Style));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style)
|
||||||
|
{
|
||||||
|
m_Parts.push_back(new cClientTranslatedPart(a_TranslationID, a_Parameters, a_Style));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::AddUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style)
|
||||||
|
{
|
||||||
|
m_Parts.push_back(new cUrlPart(a_Text, a_Url, a_Style));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::AddRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style)
|
||||||
|
{
|
||||||
|
m_Parts.push_back(new cRunCommandPart(a_Text, a_Command, a_Style));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style)
|
||||||
|
{
|
||||||
|
m_Parts.push_back(new cSuggestCommandPart(a_Text, a_SuggestedCommand, a_Style));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::ParseText(const AString & a_ParseText)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompositeChat::SetMessageType(eMessageType a_MessageType)
|
||||||
|
{
|
||||||
|
m_MessageType = a_MessageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cBasePart:
|
||||||
|
|
||||||
|
cCompositeChat::cBasePart::cBasePart(cCompositeChat::ePartType a_PartType, const AString & a_Text, const AString & a_Style) :
|
||||||
|
m_PartType(a_PartType),
|
||||||
|
m_Text(a_Text),
|
||||||
|
m_Style(a_Style)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cTextPart:
|
||||||
|
|
||||||
|
cCompositeChat::cTextPart::cTextPart(const AString & a_Text, const AString &a_Style) :
|
||||||
|
super(ptText, a_Text, a_Style)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cClientTranslatedPart:
|
||||||
|
|
||||||
|
cCompositeChat::cClientTranslatedPart::cClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style) :
|
||||||
|
super(ptClientTranslated, a_TranslationID, a_Style),
|
||||||
|
m_Parameters(a_Parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cUrlPart:
|
||||||
|
|
||||||
|
cCompositeChat::cUrlPart::cUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style) :
|
||||||
|
super(ptUrl, a_Text, a_Style),
|
||||||
|
m_Url(a_Url)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cCommandPart:
|
||||||
|
|
||||||
|
cCompositeChat::cCommandPart::cCommandPart(ePartType a_PartType, const AString & a_Text, const AString & a_Command, const AString & a_Style) :
|
||||||
|
super(a_PartType, a_Text, a_Style),
|
||||||
|
m_Command(a_Command)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cRunCommandPart:
|
||||||
|
|
||||||
|
cCompositeChat::cRunCommandPart::cRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style) :
|
||||||
|
super(ptRunCommand, a_Text, a_Command, a_Style)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompositeChat::cSuggestCommandPart:
|
||||||
|
|
||||||
|
cCompositeChat::cSuggestCommandPart::cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style) :
|
||||||
|
super(ptSuggestCommand, a_Text, a_Command, a_Style)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
|
||||||
|
// CompositeChat.h
|
||||||
|
|
||||||
|
// Declares the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd)
|
||||||
|
|
||||||
|
#include "Defines.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
/** Container for a single chat message composed of multiple functional parts.
|
||||||
|
Each part corresponds roughly to the behavior supported by the client messaging:
|
||||||
|
- plain text, optionaly colorized / styled
|
||||||
|
- clickable URLs
|
||||||
|
- clickable commands (run)
|
||||||
|
- clickable commands (suggest)
|
||||||
|
Each part has a text assigned to it that can be styled. The style is specified using a string,
|
||||||
|
each character / character combination in the string specifies the style to use:
|
||||||
|
- b = bold
|
||||||
|
- i = italic
|
||||||
|
- u = underlined
|
||||||
|
- s = strikethrough
|
||||||
|
- o = obfuscated
|
||||||
|
- @X = color X (X is 0 - 9 or a - f, same as dye meta
|
||||||
|
If the protocol version doesn't support all the features, it degrades gracefully.
|
||||||
|
*/
|
||||||
|
class cCompositeChat
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
enum ePartType
|
||||||
|
{
|
||||||
|
ptText,
|
||||||
|
ptClientTranslated,
|
||||||
|
ptUrl,
|
||||||
|
ptRunCommand,
|
||||||
|
ptSuggestCommand,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cBasePart
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ePartType m_PartType;
|
||||||
|
AString m_Text;
|
||||||
|
AString m_Style;
|
||||||
|
|
||||||
|
cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cTextPart :
|
||||||
|
public cBasePart
|
||||||
|
{
|
||||||
|
typedef cBasePart super;
|
||||||
|
public:
|
||||||
|
cTextPart(const AString & a_Text, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cClientTranslatedPart :
|
||||||
|
public cBasePart
|
||||||
|
{
|
||||||
|
typedef cBasePart super;
|
||||||
|
public:
|
||||||
|
AStringVector m_Parameters;
|
||||||
|
|
||||||
|
cClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cUrlPart :
|
||||||
|
public cBasePart
|
||||||
|
{
|
||||||
|
typedef cBasePart super;
|
||||||
|
public:
|
||||||
|
AString m_Url;
|
||||||
|
|
||||||
|
cUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cCommandPart :
|
||||||
|
public cBasePart
|
||||||
|
{
|
||||||
|
typedef cBasePart super;
|
||||||
|
public:
|
||||||
|
AString m_Command;
|
||||||
|
|
||||||
|
cCommandPart(ePartType a_PartType, const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cRunCommandPart :
|
||||||
|
public cCommandPart
|
||||||
|
{
|
||||||
|
typedef cCommandPart super;
|
||||||
|
public:
|
||||||
|
cRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class cSuggestCommandPart :
|
||||||
|
public cCommandPart
|
||||||
|
{
|
||||||
|
typedef cCommandPart super;
|
||||||
|
public:
|
||||||
|
cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
|
||||||
|
} ;
|
||||||
|
|
||||||
|
typedef std::vector<cBasePart *> cParts;
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
/** Creates a new empty chat message */
|
||||||
|
cCompositeChat(void);
|
||||||
|
|
||||||
|
/** Creates a new chat message and parses the text into parts.
|
||||||
|
Recognizes "http:" and "https:" links and @color-codes.
|
||||||
|
Uses ParseText() for the actual parsing. */
|
||||||
|
cCompositeChat(const AString & a_ParseText);
|
||||||
|
|
||||||
|
~cCompositeChat();
|
||||||
|
|
||||||
|
/** Removes all parts from the object. */
|
||||||
|
void Clear(void);
|
||||||
|
|
||||||
|
/** Adds a plain text part, with optional style.
|
||||||
|
The default style is plain white text. */
|
||||||
|
void AddTextPart(const AString & a_Message, const AString & a_Style = "");
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
/** Adds a part that is translated client-side, with the formatting parameters and optional style.
|
||||||
|
Exported in ManualBindings due to AStringVector usage - Lua uses an array-table of strings. */
|
||||||
|
void AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = "");
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
/** Adds a part that opens an URL when clicked.
|
||||||
|
The default style is underlined light blue text. */
|
||||||
|
void AddUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style = "u@c");
|
||||||
|
|
||||||
|
/** Adds a part that runs a command when clicked.
|
||||||
|
The default style is underlined light green text. */
|
||||||
|
void AddRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "u@a");
|
||||||
|
|
||||||
|
/** Adds a part that suggests a command (enters it into the chat message area, but doesn't send) when clicked.
|
||||||
|
The default style is underlined yellow text. */
|
||||||
|
void AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style = "u@b");
|
||||||
|
|
||||||
|
/** Parses text into various parts, adds those.
|
||||||
|
Recognizes "http:" and "https:" URLs and @color-codes. */
|
||||||
|
void ParseText(const AString & a_ParseText);
|
||||||
|
|
||||||
|
/** Sets the message type, which is indicated by prefixes added to the message when serializing. */
|
||||||
|
void SetMessageType(eMessageType a_MessageType);
|
||||||
|
|
||||||
|
/** Returns the message type set previously by SetMessageType(). */
|
||||||
|
eMessageType GetMessageType(void) const { return m_MessageType; }
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
const cParts & GetParts(void) const { return m_Parts; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** All the parts that */
|
||||||
|
cParts m_Parts;
|
||||||
|
|
||||||
|
/** The message type, as indicated by prefixes. */
|
||||||
|
eMessageType m_MessageType;
|
||||||
|
} ; // tolua_export
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -441,7 +441,10 @@ inline float GetSpecialSignf( float a_Val )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum ChatPrefixCodes
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
enum eMessageType
|
||||||
{
|
{
|
||||||
// http://forum.mc-server.org/showthread.php?tid=1212
|
// http://forum.mc-server.org/showthread.php?tid=1212
|
||||||
// MessageType...
|
// MessageType...
|
||||||
|
@ -458,7 +461,9 @@ enum ChatPrefixCodes
|
||||||
mtLeave, // A player has left the server
|
mtLeave, // A player has left the server
|
||||||
};
|
};
|
||||||
|
|
||||||
// tolua_begin
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Normalizes an angle in degrees to the [-180, +180) range: */
|
/** Normalizes an angle in degrees to the [-180, +180) range: */
|
||||||
inline double NormalizeAngleDegrees(const double a_Degrees)
|
inline double NormalizeAngleDegrees(const double a_Degrees)
|
||||||
|
|
|
@ -203,6 +203,7 @@ public:
|
||||||
void SendMessageWarning (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtWarning); }
|
void SendMessageWarning (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtWarning); }
|
||||||
void SendMessageFatal (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
|
void SendMessageFatal (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
|
||||||
void SendMessagePrivateMsg(const AString & a_Message, const AString & a_Sender) { m_ClientHandle->SendChat(a_Message, mtPrivateMessage, a_Sender); }
|
void SendMessagePrivateMsg(const AString & a_Message, const AString & a_Sender) { m_ClientHandle->SendChat(a_Message, mtPrivateMessage, a_Sender); }
|
||||||
|
void SendMessage (const cCompositeChat & a_Message) { m_ClientHandle->SendChat(a_Message); }
|
||||||
|
|
||||||
const AString & GetName(void) const { return m_PlayerName; }
|
const AString & GetName(void) const { return m_PlayerName; }
|
||||||
void SetName(const AString & a_Name) { m_PlayerName = a_Name; }
|
void SetName(const AString & a_Name) { m_PlayerName = a_Name; }
|
||||||
|
|
|
@ -28,6 +28,7 @@ class cWorld;
|
||||||
class cMonster;
|
class cMonster;
|
||||||
class cChunkDataSerializer;
|
class cChunkDataSerializer;
|
||||||
class cFallingBlock;
|
class cFallingBlock;
|
||||||
|
class cCompositeChat;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ public:
|
||||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
|
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
|
||||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0;
|
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0;
|
||||||
virtual void SendChat (const AString & a_Message) = 0;
|
virtual void SendChat (const AString & a_Message) = 0;
|
||||||
|
virtual void SendChat (const cCompositeChat & a_Message) = 0;
|
||||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
|
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
|
||||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 0;
|
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 0;
|
||||||
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
|
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
|
||||||
|
|
|
@ -32,6 +32,8 @@ Documentation:
|
||||||
|
|
||||||
#include "../Mobs/IncludeAllMonsters.h"
|
#include "../Mobs/IncludeAllMonsters.h"
|
||||||
|
|
||||||
|
#include "../CompositeChat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,6 +235,42 @@ void cProtocol125::SendChat(const AString & a_Message)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol125::SendChat(const cCompositeChat & a_Message)
|
||||||
|
{
|
||||||
|
// This version doesn't support composite messages, just extract each part's text and use it:
|
||||||
|
AString Msg;
|
||||||
|
const cCompositeChat::cParts & Parts = a_Message.GetParts();
|
||||||
|
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
switch ((*itr)->m_PartType)
|
||||||
|
{
|
||||||
|
case cCompositeChat::ptText:
|
||||||
|
case cCompositeChat::ptClientTranslated:
|
||||||
|
case cCompositeChat::ptRunCommand:
|
||||||
|
case cCompositeChat::ptSuggestCommand:
|
||||||
|
{
|
||||||
|
Msg.append((*itr)->m_Text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cCompositeChat::ptUrl:
|
||||||
|
{
|
||||||
|
Msg.append(((cCompositeChat::cUrlPart *)(*itr))->m_Url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // switch (PartType)
|
||||||
|
} // for itr - Parts[]
|
||||||
|
|
||||||
|
// Send the message:
|
||||||
|
cCSLock Lock(m_CSPacket);
|
||||||
|
WriteByte (PACKET_CHAT);
|
||||||
|
WriteString(Msg);
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
||||||
virtual void SendChat (const AString & a_Message) override;
|
virtual void SendChat (const AString & a_Message) override;
|
||||||
|
virtual void SendChat (const cCompositeChat & a_Message) override;
|
||||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||||
|
|
|
@ -8,6 +8,7 @@ Implements the 1.7.x protocol classes:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
#include "json/json.h"
|
||||||
#include "Protocol17x.h"
|
#include "Protocol17x.h"
|
||||||
#include "ChunkDataSerializer.h"
|
#include "ChunkDataSerializer.h"
|
||||||
#include "../ClientHandle.h"
|
#include "../ClientHandle.h"
|
||||||
|
@ -25,6 +26,7 @@ Implements the 1.7.x protocol classes:
|
||||||
#include "../Mobs/IncludeAllMonsters.h"
|
#include "../Mobs/IncludeAllMonsters.h"
|
||||||
#include "../UI/Window.h"
|
#include "../UI/Window.h"
|
||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
|
#include "../CompositeChat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,6 +202,78 @@ void cProtocol172::SendChat(const AString & a_Message)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol172::SendChat(const cCompositeChat & a_Message)
|
||||||
|
{
|
||||||
|
// Compose the complete Json string to send:
|
||||||
|
Json::Value msg;
|
||||||
|
msg["text"] = ""; // The client crashes without this
|
||||||
|
const cCompositeChat::cParts & Parts = a_Message.GetParts();
|
||||||
|
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
Json::Value Part;
|
||||||
|
switch ((*itr)->m_PartType)
|
||||||
|
{
|
||||||
|
case cCompositeChat::ptText:
|
||||||
|
{
|
||||||
|
Part["text"] = (*itr)->m_Text;
|
||||||
|
AddChatPartStyle(Part, (*itr)->m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptClientTranslated:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
|
||||||
|
Part["translate"] = p.m_Text;
|
||||||
|
Json::Value With;
|
||||||
|
for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
|
||||||
|
{
|
||||||
|
With.append(*itrW);
|
||||||
|
}
|
||||||
|
if (!p.m_Parameters.empty())
|
||||||
|
{
|
||||||
|
Part["with"] = With;
|
||||||
|
}
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptUrl:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
|
||||||
|
Part["text"] = p.m_Text;
|
||||||
|
Json::Value Url;
|
||||||
|
Url["action"] = "open_url";
|
||||||
|
Url["value"] = p.m_Url;
|
||||||
|
Part["clickEvent"] = Url;
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptSuggestCommand:
|
||||||
|
case cCompositeChat::ptRunCommand:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
|
||||||
|
Part["text"] = p.m_Text;
|
||||||
|
Json::Value Cmd;
|
||||||
|
Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
|
||||||
|
Cmd["value"] = p.m_Command;
|
||||||
|
Part["clickEvent"] = Cmd;
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg["extra"].append(Part);
|
||||||
|
} // for itr - Parts[]
|
||||||
|
|
||||||
|
// Send the message to the client:
|
||||||
|
cPacketizer Pkt(*this, 0x02);
|
||||||
|
Pkt.WriteString(msg.toStyledString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
||||||
{
|
{
|
||||||
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
|
||||||
|
@ -1979,6 +2053,85 @@ void cProtocol172::StartEncryption(const Byte * a_Key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol172::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle)
|
||||||
|
{
|
||||||
|
size_t len = a_PartStyle.length();
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
switch (a_PartStyle[i])
|
||||||
|
{
|
||||||
|
case 'b':
|
||||||
|
{
|
||||||
|
// bold
|
||||||
|
a_Value["bold"] = Json::Value(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
{
|
||||||
|
// italic
|
||||||
|
a_Value["italic"] = Json::Value(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
{
|
||||||
|
// Underlined
|
||||||
|
a_Value["underlined"] = Json::Value(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
// strikethrough
|
||||||
|
a_Value["strikethrough"] = Json::Value(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
{
|
||||||
|
// obfuscated
|
||||||
|
a_Value["obfuscated"] = Json::Value(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '@':
|
||||||
|
{
|
||||||
|
// Color, specified by the next char:
|
||||||
|
i++;
|
||||||
|
if (i >= len)
|
||||||
|
{
|
||||||
|
// String too short, didn't contain a color
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (a_PartStyle[i])
|
||||||
|
{
|
||||||
|
case '0': a_Value["color"] = Json::Value("black"); break;
|
||||||
|
case '1': a_Value["color"] = Json::Value("dark_blue"); break;
|
||||||
|
case '2': a_Value["color"] = Json::Value("dark_green"); break;
|
||||||
|
case '3': a_Value["color"] = Json::Value("dark_aqua"); break;
|
||||||
|
case '4': a_Value["color"] = Json::Value("dark_red"); break;
|
||||||
|
case '5': a_Value["color"] = Json::Value("dark_purple"); break;
|
||||||
|
case '6': a_Value["color"] = Json::Value("gold"); break;
|
||||||
|
case '7': a_Value["color"] = Json::Value("gray"); break;
|
||||||
|
case '8': a_Value["color"] = Json::Value("dark_gray"); break;
|
||||||
|
case '9': a_Value["color"] = Json::Value("blue"); break;
|
||||||
|
case 'a': a_Value["color"] = Json::Value("green"); break;
|
||||||
|
case 'b': a_Value["color"] = Json::Value("aqua"); break;
|
||||||
|
case 'c': a_Value["color"] = Json::Value("red"); break;
|
||||||
|
case 'd': a_Value["color"] = Json::Value("light_purple"); break;
|
||||||
|
case 'e': a_Value["color"] = Json::Value("yellow"); break;
|
||||||
|
case 'f': a_Value["color"] = Json::Value("white"); break;
|
||||||
|
} // switch (color)
|
||||||
|
} // case '@'
|
||||||
|
} // switch (Style[i])
|
||||||
|
} // for i - a_PartStyle[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cProtocol172::cPacketizer:
|
// cProtocol172::cPacketizer:
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,16 @@ Declares the 1.7.x protocol classes:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fwd:
|
||||||
|
namespace Json
|
||||||
|
{
|
||||||
|
class Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cProtocol172 :
|
class cProtocol172 :
|
||||||
public cProtocol
|
public cProtocol
|
||||||
{
|
{
|
||||||
|
@ -45,16 +55,17 @@ public:
|
||||||
|
|
||||||
cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
||||||
|
|
||||||
/// Called when client sends some data:
|
/** Called when client sends some data: */
|
||||||
virtual void DataReceived(const char * a_Data, int a_Size) override;
|
virtual void DataReceived(const char * a_Data, int a_Size) override;
|
||||||
|
|
||||||
/// Sending stuff to clients (alphabetically sorted):
|
/** Sending stuff to clients (alphabetically sorted): */
|
||||||
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
|
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
|
||||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
||||||
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
||||||
virtual void SendChat (const AString & a_Message) override;
|
virtual void SendChat (const AString & a_Message) override;
|
||||||
|
virtual void SendChat (const cCompositeChat & a_Message) override;
|
||||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||||
|
@ -117,7 +128,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed
|
/** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */
|
||||||
class cPacketizer
|
class cPacketizer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -206,16 +217,16 @@ protected:
|
||||||
|
|
||||||
AString m_AuthServerID;
|
AString m_AuthServerID;
|
||||||
|
|
||||||
/// State of the protocol. 1 = status, 2 = login, 3 = game
|
/** State of the protocol. 1 = status, 2 = login, 3 = game */
|
||||||
UInt32 m_State;
|
UInt32 m_State;
|
||||||
|
|
||||||
/// Buffer for the received data
|
/** Buffer for the received data */
|
||||||
cByteBuffer m_ReceivedData;
|
cByteBuffer m_ReceivedData;
|
||||||
|
|
||||||
/// Buffer for composing the outgoing packets, through cPacketizer
|
/** Buffer for composing the outgoing packets, through cPacketizer */
|
||||||
cByteBuffer m_OutPacketBuffer;
|
cByteBuffer m_OutPacketBuffer;
|
||||||
|
|
||||||
/// Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer)
|
/** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */
|
||||||
cByteBuffer m_OutPacketLenBuffer;
|
cByteBuffer m_OutPacketLenBuffer;
|
||||||
|
|
||||||
bool m_IsEncrypted;
|
bool m_IsEncrypted;
|
||||||
|
@ -227,7 +238,7 @@ protected:
|
||||||
cFile m_CommLogFile;
|
cFile m_CommLogFile;
|
||||||
|
|
||||||
|
|
||||||
/// Adds the received (unencrypted) data to m_ReceivedData, parses complete packets
|
/** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */
|
||||||
void AddReceivedData(const char * a_Data, int a_Size);
|
void AddReceivedData(const char * a_Data, int a_Size);
|
||||||
|
|
||||||
/** Reads and handles the packet. The packet length and type have already been read.
|
/** Reads and handles the packet. The packet length and type have already been read.
|
||||||
|
@ -268,21 +279,24 @@ protected:
|
||||||
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
|
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
|
||||||
|
|
||||||
|
|
||||||
/// Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here.
|
/** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */
|
||||||
void WritePacket(cByteBuffer & a_Packet);
|
void WritePacket(cByteBuffer & a_Packet);
|
||||||
|
|
||||||
/// Sends the data to the client, encrypting them if needed.
|
/** Sends the data to the client, encrypting them if needed. */
|
||||||
virtual void SendData(const char * a_Data, int a_Size) override;
|
virtual void SendData(const char * a_Data, int a_Size) override;
|
||||||
|
|
||||||
void SendCompass(const cWorld & a_World);
|
void SendCompass(const cWorld & a_World);
|
||||||
|
|
||||||
/// Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data
|
/** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */
|
||||||
bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
|
bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
|
||||||
|
|
||||||
/// Parses item metadata as read by ReadItem(), into the item enchantments.
|
/** Parses item metadata as read by ReadItem(), into the item enchantments. */
|
||||||
void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);
|
void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);
|
||||||
|
|
||||||
void StartEncryption(const Byte * a_Key);
|
void StartEncryption(const Byte * a_Key);
|
||||||
|
|
||||||
|
/** Adds the chat part's style (represented by the part's stylestring) into the Json object. */
|
||||||
|
void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle);
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,16 @@ void cProtocolRecognizer::SendChat(const AString & a_Message)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message)
|
||||||
|
{
|
||||||
|
ASSERT(m_Protocol != NULL);
|
||||||
|
m_Protocol->SendChat(a_Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
||||||
{
|
{
|
||||||
ASSERT(m_Protocol != NULL);
|
ASSERT(m_Protocol != NULL);
|
||||||
|
|
|
@ -68,6 +68,7 @@ public:
|
||||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||||
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
|
||||||
virtual void SendChat (const AString & a_Message) override;
|
virtual void SendChat (const AString & a_Message) override;
|
||||||
|
virtual void SendChat (const cCompositeChat & a_Message) override;
|
||||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||||
|
|
14
src/Root.cpp
14
src/Root.cpp
|
@ -543,7 +543,7 @@ void cRoot::ReloadGroups(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cRoot::LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix)
|
void cRoot::LoopWorldsAndBroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix)
|
||||||
{
|
{
|
||||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr)
|
for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
|
@ -555,6 +555,18 @@ void cRoot::LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cRoot::BroadcastChat(const cCompositeChat & a_Message)
|
||||||
|
{
|
||||||
|
for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
itr->second->BroadcastChat(a_Message);
|
||||||
|
} // for itr - m_WorldsByName[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback)
|
bool cRoot::ForEachPlayer(cPlayerListCallback & a_Callback)
|
||||||
{
|
{
|
||||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
for (WorldMap::iterator itr = m_WorldsByName.begin(), itr2 = itr; itr != m_WorldsByName.end(); itr = itr2)
|
||||||
|
|
|
@ -20,7 +20,8 @@ class cPluginManager;
|
||||||
class cServer;
|
class cServer;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
class cCommandOutputCallback ;
|
class cCommandOutputCallback;
|
||||||
|
class cCompositeChat;
|
||||||
|
|
||||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
||||||
typedef cItemCallback<cWorld> cWorldListCallback;
|
typedef cItemCallback<cWorld> cWorldListCallback;
|
||||||
|
@ -108,7 +109,7 @@ public:
|
||||||
/// Finds a player from a partial or complete player name and calls the callback - case-insensitive
|
/// Finds a player from a partial or complete player name and calls the callback - case-insensitive
|
||||||
bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
void LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix);
|
void LoopWorldsAndBroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix);
|
||||||
void BroadcastChatJoin (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtJoin); }
|
void BroadcastChatJoin (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtJoin); }
|
||||||
void BroadcastChatLeave (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtLeave); }
|
void BroadcastChatLeave (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtLeave); }
|
||||||
void BroadcastChatDeath (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtDeath); }
|
void BroadcastChatDeath (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtDeath); }
|
||||||
|
@ -122,6 +123,7 @@ public:
|
||||||
void BroadcastChatSuccess(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtSuccess); }
|
void BroadcastChatSuccess(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtSuccess); }
|
||||||
void BroadcastChatWarning(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtWarning); }
|
void BroadcastChatWarning(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtWarning); }
|
||||||
void BroadcastChatFatal (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtFailure); }
|
void BroadcastChatFatal (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtFailure); }
|
||||||
|
void BroadcastChat (const cCompositeChat & a_Message);
|
||||||
|
|
||||||
/// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API
|
/// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API
|
||||||
static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum);
|
static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum);
|
||||||
|
|
|
@ -1747,7 +1747,7 @@ void cWorld::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const cClientHandle * a_Exclude)
|
void cWorld::LoopPlayersAndBroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||||
|
@ -1765,6 +1765,24 @@ void cWorld::LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWorld::BroadcastChat(const cCompositeChat & a_Message, const cClientHandle * a_Exclude)
|
||||||
|
{
|
||||||
|
cCSLock Lock(m_CSPlayers);
|
||||||
|
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||||
|
{
|
||||||
|
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||||
|
if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ch->SendChat(a_Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
|
void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
|
||||||
{
|
{
|
||||||
m_ChunkMap->BroadcastChunkData(a_ChunkX, a_ChunkZ, a_Serializer, a_Exclude);
|
m_ChunkMap->BroadcastChunkData(a_ChunkX, a_ChunkZ, a_Serializer, a_Exclude);
|
||||||
|
|
|
@ -46,6 +46,7 @@ class cDispenserEntity;
|
||||||
class cFurnaceEntity;
|
class cFurnaceEntity;
|
||||||
class cNoteEntity;
|
class cNoteEntity;
|
||||||
class cMobCensus;
|
class cMobCensus;
|
||||||
|
class cCompositeChat;
|
||||||
|
|
||||||
typedef std::list< cPlayer * > cPlayerList;
|
typedef std::list< cPlayer * > cPlayerList;
|
||||||
|
|
||||||
|
@ -167,7 +168,7 @@ public:
|
||||||
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL);
|
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL);
|
||||||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
||||||
|
|
||||||
void LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const cClientHandle * a_Exclude = NULL);
|
void LoopPlayersAndBroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix, const cClientHandle * a_Exclude = NULL);
|
||||||
void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtDeath, a_Exclude); }
|
void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtDeath, a_Exclude); }
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
@ -177,6 +178,7 @@ public:
|
||||||
void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtSuccess, a_Exclude); }
|
void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtSuccess, a_Exclude); }
|
||||||
void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtWarning, a_Exclude); }
|
void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtWarning, a_Exclude); }
|
||||||
void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtFailure, a_Exclude); }
|
void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtFailure, a_Exclude); }
|
||||||
|
void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = NULL);
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||||
|
|
Loading…
Reference in New Issue