2014-01-18 08:16:47 -05:00
// CommandBlockEntity.cpp
// Implements the cCommandBlockEntity class representing a single command block in the world
# include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
# include "CommandBlockEntity.h"
2014-01-18 19:54:38 -05:00
# include "../CommandOutput.h"
# include "../Root.h"
2014-07-17 16:15:34 -04:00
# include "../Server.h" // ExecuteConsoleCommand()
2014-08-29 08:41:50 -04:00
# include "../ChatColor.h"
2014-09-26 13:13:19 -04:00
# include "../World.h"
# include "../ClientHandle.h"
2014-01-18 09:59:33 -05:00
2014-01-18 08:16:47 -05:00
2017-06-15 09:32:33 -04:00
cCommandBlockEntity : : cCommandBlockEntity ( BLOCKTYPE a_BlockType , NIBBLETYPE a_BlockMeta , int a_BlockX , int a_BlockY , int a_BlockZ , cWorld * a_World ) :
Super ( a_BlockType , a_BlockMeta , a_BlockX , a_BlockY , a_BlockZ , a_World ) ,
2014-01-18 08:16:47 -05:00
m_ShouldExecute ( false ) ,
2014-04-26 18:32:14 -04:00
m_Result ( 0 )
2017-06-15 09:32:33 -04:00
{
ASSERT ( a_BlockType = = E_BLOCK_COMMAND_BLOCK ) ;
}
2014-01-18 08:16:47 -05:00
2015-12-01 17:12:44 -05:00
bool cCommandBlockEntity : : UsedBy ( cPlayer * a_Player )
2014-01-18 08:16:47 -05:00
{
2014-01-18 14:27:54 -05:00
// Nothing to do
UNUSED ( a_Player ) ;
2015-12-01 17:12:44 -05:00
return true ;
2014-01-18 08:16:47 -05:00
}
void cCommandBlockEntity : : SetCommand ( const AString & a_Cmd )
{
2014-01-18 09:59:33 -05:00
m_Command = a_Cmd ;
2014-01-18 19:54:38 -05:00
/*
Vanilla requires that the server send a Block Entity Update after a command has been set
Therefore , command blocks don ' t support on - the - fly ( when window is open ) updating of a command and therefore . . .
. . . the following code can ' t be put in UsedBy just before the window opens
Just documenting my experience in getting this to work : P
*/
m_World - > BroadcastBlockEntity ( GetPosX ( ) , GetPosY ( ) , GetPosZ ( ) ) ;
2014-01-18 08:16:47 -05:00
}
2014-01-18 08:40:47 -05:00
void cCommandBlockEntity : : SetLastOutput ( const AString & a_LastOut )
{
2014-01-19 08:25:35 -05:00
m_World - > BroadcastBlockEntity ( GetPosX ( ) , GetPosY ( ) , GetPosZ ( ) ) ;
2014-01-18 08:40:47 -05:00
m_LastOutput = a_LastOut ;
}
void cCommandBlockEntity : : SetResult ( const NIBBLETYPE a_Result )
{
m_Result = a_Result ;
}
2014-01-18 08:16:47 -05:00
const AString & cCommandBlockEntity : : GetCommand ( void ) const
{
return m_Command ;
}
const AString & cCommandBlockEntity : : GetLastOutput ( void ) const
{
return m_LastOutput ;
}
2014-01-18 08:40:47 -05:00
NIBBLETYPE cCommandBlockEntity : : GetResult ( void ) const
{
return m_Result ;
}
2014-01-18 08:16:47 -05:00
void cCommandBlockEntity : : Activate ( void )
{
m_ShouldExecute = true ;
}
2017-06-15 09:32:33 -04:00
void cCommandBlockEntity : : CopyFrom ( const cBlockEntity & a_Src )
{
Super : : CopyFrom ( a_Src ) ;
auto & src = reinterpret_cast < const cCommandBlockEntity & > ( a_Src ) ;
m_Command = src . m_Command ;
m_LastOutput = src . m_LastOutput ;
m_Result = src . m_Result ;
m_ShouldExecute = src . m_ShouldExecute ;
}
2015-01-11 16:12:26 -05:00
bool cCommandBlockEntity : : Tick ( std : : chrono : : milliseconds a_Dt , cChunk & a_Chunk )
2014-01-18 08:16:47 -05:00
{
2014-02-24 14:29:59 -05:00
UNUSED ( a_Dt ) ;
UNUSED ( a_Chunk ) ;
2014-01-18 08:16:47 -05:00
if ( ! m_ShouldExecute )
{
return false ;
}
2016-02-05 16:45:45 -05:00
2014-01-18 08:16:47 -05:00
m_ShouldExecute = false ;
Execute ( ) ;
return true ;
}
void cCommandBlockEntity : : SendTo ( cClientHandle & a_Client )
{
2014-01-19 14:42:25 -05:00
a_Client . SendUpdateBlockEntity ( * this ) ;
2014-01-18 08:16:47 -05:00
}
void cCommandBlockEntity : : Execute ( )
{
2014-10-20 16:55:07 -04:00
ASSERT ( m_World ! = nullptr ) ; // Execute should not be called before the command block is attached to a world
2016-02-05 16:45:45 -05:00
2014-08-31 16:14:42 -04:00
if ( ! m_World - > AreCommandBlocksEnabled ( ) )
2014-01-23 07:57:04 -05:00
{
2014-08-31 16:14:42 -04:00
return ;
2014-01-23 07:57:04 -05:00
}
2014-01-18 09:59:33 -05:00
class CommandBlockOutCb :
public cCommandOutputCallback
{
2014-01-23 08:14:33 -05:00
cCommandBlockEntity * m_CmdBlock ;
2014-01-18 09:59:33 -05:00
public :
2014-01-23 08:14:33 -05:00
CommandBlockOutCb ( cCommandBlockEntity * a_CmdBlock ) : m_CmdBlock ( a_CmdBlock ) { }
2014-01-18 09:59:33 -05:00
virtual void Out ( const AString & a_Text )
{
// Overwrite field
2014-08-29 08:41:50 -04:00
m_CmdBlock - > SetLastOutput ( cClientHandle : : FormatChatPrefix ( m_CmdBlock - > GetWorld ( ) - > ShouldUseChatPrefixes ( ) , " SUCCESS " , cChatColor : : Green , cChatColor : : White ) + a_Text ) ;
2014-01-18 09:59:33 -05:00
}
} CmdBlockOutCb ( this ) ;
2014-08-30 16:24:04 -04:00
// Administrator commands are not executable by command blocks:
if (
2014-08-29 08:41:50 -04:00
( m_Command ! = " stop " ) & &
( m_Command ! = " restart " ) & &
( m_Command ! = " kick " ) & &
( m_Command ! = " ban " ) & &
( m_Command ! = " ipban " )
2014-08-30 16:24:04 -04:00
)
2014-08-29 08:41:50 -04:00
{
cServer * Server = cRoot : : Get ( ) - > GetServer ( ) ;
LOGD ( " cCommandBlockEntity: Executing command %s " , m_Command . c_str ( ) ) ;
Server - > ExecuteConsoleCommand ( m_Command , CmdBlockOutCb ) ;
}
else
{
SetLastOutput ( cClientHandle : : FormatChatPrefix ( GetWorld ( ) - > ShouldUseChatPrefixes ( ) , " FAILURE " , cChatColor : : Rose , cChatColor : : White ) + " Adminstration commands can not be executed " ) ;
LOGD ( " cCommandBlockEntity: Prevented execution of administration command %s " , m_Command . c_str ( ) ) ;
}
2014-01-18 08:40:47 -05:00
2014-01-18 09:59:33 -05:00
// TODO 2014-01-18 xdot: Update the signal strength.
2014-01-18 08:40:47 -05:00
m_Result = 0 ;
2014-01-18 08:16:47 -05:00
}