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 "json/json.h"
# include "CommandBlockEntity.h"
# include "../Entities/Player.h"
2014-01-18 19:54:38 -05:00
# include "../WorldStorage/FastNBT.h"
2014-01-18 08:16:47 -05:00
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-02-24 16:47:58 -05:00
# include "../Chunk.h"
2014-08-29 08:41:50 -04:00
# include "../ChatColor.h"
2014-01-18 09:59:33 -05:00
2014-01-18 08:16:47 -05:00
cCommandBlockEntity : : cCommandBlockEntity ( int a_X , int a_Y , int a_Z , cWorld * a_World ) :
super ( E_BLOCK_COMMAND_BLOCK , a_X , a_Y , a_Z , a_World ) ,
m_ShouldExecute ( false ) ,
2014-04-26 18:32:14 -04:00
m_IsPowered ( false ) ,
m_Result ( 0 )
2014-01-18 14:27:54 -05:00
{ }
2014-01-18 08:16:47 -05:00
void cCommandBlockEntity : : UsedBy ( cPlayer * a_Player )
{
2014-01-18 14:27:54 -05:00
// Nothing to do
UNUSED ( a_Player ) ;
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 ;
}
void cCommandBlockEntity : : SetRedstonePower ( bool a_IsPowered )
{
if ( a_IsPowered & & ! m_IsPowered )
{
Activate ( ) ;
}
m_IsPowered = a_IsPowered ;
}
bool cCommandBlockEntity : : Tick ( float a_Dt , cChunk & a_Chunk )
{
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 ;
}
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
}
bool cCommandBlockEntity : : LoadFromJson ( const Json : : Value & a_Value )
{
2014-01-23 07:57:04 -05:00
m_PosX = a_Value . get ( " x " , 0 ) . asInt ( ) ;
m_PosY = a_Value . get ( " y " , 0 ) . asInt ( ) ;
m_PosZ = a_Value . get ( " z " , 0 ) . asInt ( ) ;
2014-01-18 08:16:47 -05:00
2014-01-23 07:57:04 -05:00
m_Command = a_Value . get ( " Command " , " " ) . asString ( ) ;
m_LastOutput = a_Value . get ( " LastOutput " , " " ) . asString ( ) ;
2014-04-03 03:27:17 -04:00
m_Result = ( NIBBLETYPE ) a_Value . get ( " SuccessCount " , 0 ) . asInt ( ) ;
2014-01-18 08:16:47 -05:00
return true ;
}
void cCommandBlockEntity : : SaveToJson ( Json : : Value & a_Value )
{
2014-01-23 07:57:04 -05:00
a_Value [ " x " ] = m_PosX ;
a_Value [ " y " ] = m_PosY ;
a_Value [ " z " ] = m_PosZ ;
2014-01-18 08:16:47 -05:00
2014-01-23 07:57:04 -05:00
a_Value [ " Command " ] = m_Command ;
a_Value [ " LastOutput " ] = m_LastOutput ;
a_Value [ " SuccessCount " ] = m_Result ;
2014-01-18 08:16:47 -05:00
}
void cCommandBlockEntity : : Execute ( )
{
2014-01-23 08:14:33 -05:00
if ( m_World ! = NULL )
2014-01-23 07:57:04 -05:00
{
if ( ! m_World - > AreCommandBlocksEnabled ( ) )
{
return ;
}
}
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-29 08:41:50 -04:00
if ( // Administrator commands are not executable by command blocks
( m_Command ! = " stop " ) & &
( m_Command ! = " restart " ) & &
( m_Command ! = " kick " ) & &
( m_Command ! = " ban " ) & &
( m_Command ! = " ipban " )
)
{
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
}