0ad/source/network/NetMessage.cpp

1528 lines
33 KiB
C++
Raw Normal View History

/**
*-----------------------------------------------------------------------------
* FILE : NetMessage.cpp
* PROJECT : 0 A.D.
* DESCRIPTION :
*-----------------------------------------------------------------------------
*/
// INCLUDES
#include "precompiled.h"
#include "simulation/Entity.h"
#include "ps/Vector2D.h"
#define ALLNETMSGS_IMPLEMENT
#include "NetMessage.h"
#include "ps/CLogger.h"
#include "Network.h"
#include <stdio.h>
#include <map>
// DEFINES
// Please don't modify the deserializer map outside the ONCE-block in DeserializeMessage
//typedef std::map< NetMessageType, NetMessageDeserializer > MessageDeserializerMap;
//MessageDeserializerMap g_DeserializerMap;
//-----------------------------------------------------------------------------
// Name: CNetMessage()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetMessage::CNetMessage( void )
{
m_Type = NMT_INVALID;
m_Dirty = false;
}
//-----------------------------------------------------------------------------
// Name: CNetMessage()
// Desc: Constructor
//-----------------------------------------------------------------------------
CNetMessage::CNetMessage( NetMessageType type )
{
m_Type = type;
m_Dirty = false;
}
//-----------------------------------------------------------------------------
// Name: ~CNetMessage()
// Desc: Destructor
//-----------------------------------------------------------------------------
CNetMessage::~CNetMessage( void )
{
m_Dirty = false;
}
//-----------------------------------------------------------------------------
// Name: Serialize()
// Desc: Serializes the message into the buffer parameter
//-----------------------------------------------------------------------------
u8* CNetMessage::Serialize( u8* pBuffer ) const
{
// Validate parameters
if ( !pBuffer ) return NULL;
// Serialize_int_1( pBuffer, m_Type );
// Serialize_int_2( pBuffer, m_SerializeSize );
// Serialize message type and its size
*( ( NetMessageType* )pBuffer ) = m_Type;
*( ( uint* )( pBuffer + sizeof( NetMessageType ) ) ) = GetSerializedLength();
return pBuffer + sizeof( NetMessageType ) + sizeof( uint );
}
//-----------------------------------------------------------------------------
// Name: Deserialize()
// Desc: Loads this message from the specifie buffer parameter
//-----------------------------------------------------------------------------
const u8* CNetMessage::Deserialize( const u8* pStart, const u8* pEnd )
{
// Validate parameters
if ( !pStart || !pEnd ) return NULL;
// Deserialize message type and its size
// Deserialize_int_1( pStart, m_Type );
// Deserialize_int_2( pStart, m_SerializeSize );
m_Type = *( ( NetMessageType* )pStart );
uint size = *( ( uint* )( pStart + sizeof( NetMessageType ) ) );
assert( pStart + size == pEnd );
return pStart + sizeof( NetMessageType ) + sizeof( size );
}
//-----------------------------------------------------------------------------
// Name: Deserialize()
// Desc: Constructs a CNetMessage object from the specified buffer parameter
// Note: It uses the registered desrializers to create the CNetMessage object
//-----------------------------------------------------------------------------
/*CNetMessage* CNetMessage::Deserialize(
NetMessageType type,
const u8* pBuffer,
uint bufferSize )
{
ONCE
(
SNetMessageDeserializer* pDeserializer = &g_DeserializerRegistrations[ 0 ];
for ( ; pDeserializer->Deserializer; pDeserializer++ )
{
g_DeserializerMap.insert( std::make_pair(
pDeserializer->Type,
pDeserializer->Deserializer ) );
}
);
MessageDeserializerMap::const_iterator it = g_DeserializerMap.find( type );
if ( it == g_DeserializerMap.end() )
{
LOG(WARNING, LOG_CAT_NET, "Unknown message received on socket: type 0x%04x, length %u", type, length);
return NULL;
}
pfnNetMessageDeserializer pDeserializer = it->second;
if ( pDeserializer )
{
// Call deserializer
return ( pDeserializer )( pBuffer, bufferSize );
}
return NULL;
}*/
//-----------------------------------------------------------------------------
// Name: GetSerializedLength()
// Desc: Returns the size of the serialized message
//-----------------------------------------------------------------------------
size_t CNetMessage::GetSerializedLength( void ) const
{
// By default, return header size
return ( sizeof( m_Type ) + sizeof( uint ) );
}
//-----------------------------------------------------------------------------
// Name: operator ( ENetPacket* )()
// Desc: Cast to an ENetPacket structure
//-----------------------------------------------------------------------------
/*void CNetMessage::operator ENetPacket*( void )
{
// Did we already serialized the message?
if ( m_Packet )
{
// Dirty message?
if ( m_Dirty )
{
// Make room for the new message content
enet_packet_resize( m_Packet, GetSerializedLength() );
// Serialize into buffer
Serialize( m_Packet->data );
}
}
else
{
// Serialize message into temporary buffer
u8* pBuffer = new u8[ GetSerializedLength() ];
if ( !pBuffer ) return NULL;
Serialize( pBuffer );
// Create ENet packet for this message
m_Packet = enet_packet_create( pBuffer, GetSerializedLength(), ENET_PACKET_FLAG_RELIABLE );
delete [] pBuffer;
}
return m_Packet;
}*/
//-----------------------------------------------------------------------------
// Name: ToString()
// Desc: Returns a string representation for the message
//-----------------------------------------------------------------------------
CStr CNetMessage::ToString( void ) const
{
CStr ret;
// Not defined yet?
if ( GetType() == NMT_INVALID )
{
ret = "MESSAGE_TYPE_NONE { Undefined Message }";
}
else
{
ret = " Unknown Message " + CStr( GetType() );
}
return ret;
}
//-----------------------------------------------------------------------------
// Name: Clone()
// Desc: Makes a copy of the message and return it to caller
//-----------------------------------------------------------------------------
CNetMessage* CNetMessage::Clone( void ) const
{
// Create new message
CNetMessage* pCloneMessage = new CNetMessage;
if ( !pCloneMessage ) return NULL;
// Copy this message content into clone message
Copy( pCloneMessage );
return pCloneMessage;
}
//-----------------------------------------------------------------------------
// Name: Copy()
// Desc: Copies the content of this message into the message parameter
//-----------------------------------------------------------------------------
void CNetMessage::Copy( CNetMessage* pMessage ) const
{
// Validate parameter
if ( !pMessage ) return;
// Copy header information
pMessage->m_Type = m_Type;
}
//-----------------------------------------------------------------------------
// Name: ScriptingInit()
// Desc:
//-----------------------------------------------------------------------------
void CNetMessage::ScriptingInit()
{
g_ScriptingHost.DefineConstant( "NMT_GOTO", NMT_GOTO );
g_ScriptingHost.DefineConstant( "NMT_RUN", NMT_RUN );
g_ScriptingHost.DefineConstant( "NMT_PATROL", NMT_PATROL );
g_ScriptingHost.DefineConstant( "NMT_ADD_WAYPOINT", NMT_ADD_WAYPOINT );
g_ScriptingHost.DefineConstant( "NMT_GENERIC", NMT_GENERIC );
g_ScriptingHost.DefineConstant( "NMT_PRODUCE", NMT_PRODUCE );
g_ScriptingHost.DefineConstant( "NMT_PLACE_OBJECT", NMT_PLACE_OBJECT );
g_ScriptingHost.DefineConstant( "NMT_NOTIFY_REQUEST", NMT_NOTIFY_REQUEST );
g_ScriptingHost.DefineConstant( "NMT_FORMATION_GOTO", NMT_FORMATION_GOTO );
g_ScriptingHost.DefineConstant( "NMT_FORMATION_GENERIC", NMT_FORMATION_GENERIC );
}
//-----------------------------------------------------------------------------
// Name: CommandFromJSArgs()
// Desc:
//-----------------------------------------------------------------------------
CNetMessage* CNetMessage::CommandFromJSArgs(
const CEntityList &entities,
JSContext* pContext,
uintN argc,
jsval* argv,
bool isQueued )
{
uint idx = 0;
uint messageType;
// Validate parameters
if ( argv == 0 ) return NULL;
try
{
messageType = ToPrimitive< uint >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid order type" );
return NULL;
}
switch ( messageType )
{
case NMT_GOTO:
{
CGotoMessage* pMessage = new CGotoMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
return pMessage;
}
case NMT_RUN:
{
CRunMessage* pMessage = new CRunMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
return pMessage;
}
case NMT_PATROL:
{
CPatrolMessage* pMessage = new CPatrolMessage;
if ( pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
return pMessage;
}
case NMT_ADD_WAYPOINT:
{
CAddWaypointMessage* pMessage = new CAddWaypointMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
return pMessage;
}
case NMT_FORMATION_GOTO:
{
CFormationGotoMessage* pMessage = new CFormationGotoMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
return pMessage;
}
case NMT_GENERIC:
{
CGenericMessage* pMessage = new CGenericMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_OBJECT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
CEntity* pEntity = ToNative< CEntity >( argv[ idx++ ] );
if ( !pEntity )
{
STMT(
JS_ReportError( pContext, "Invalid entity parameter" );
return NULL;
);
}
pMessage->m_Target = pEntity->me;
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Action = ToPrimitive< int >( argv[ idx++ ] )
);
return pMessage;
}
case NMT_NOTIFY_REQUEST:
{
CNotifyRequestMessage* pMessage = new CNotifyRequestMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_OBJECT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
CEntity* pEntity = ToNative< CEntity >( argv[ idx++ ] );
if ( !pEntity )
{
JS_ReportError( pContext, "Invalid entity parameter" );
return NULL;
}
pMessage->m_Target = pEntity->me;
);
return pMessage;
}
case NMT_FORMATION_GENERIC:
{
CFormationGenericMessage* pMessage = new CFormationGenericMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );\
return NULL;
);
}
if ( !JSVAL_IS_OBJECT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
CEntity* pEntity = ToNative< CEntity >( argv[ idx++ ] );
if ( !pEntity )
{
STMT(
JS_ReportError( pContext, "Invalid entity parameter" );
return NULL;
);
}
pMessage->m_Target = pEntity->me;
);
return pMessage;
}
case NMT_PRODUCE:
{
CProduceMessage* pMessage = new CProduceMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Type = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_STRING( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Name = ToPrimitive< CStrW >( argv[ idx++ ] );
);
return pMessage;
}
case NMT_PLACE_OBJECT:
{
CPlaceObjectMessage* pMessage = new CPlaceObjectMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = isQueued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_STRING( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Template = ToPrimitive< CStrW >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_X = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Y = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Z = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Angle = ToPrimitive< int >( argv[ idx++ ] );
);
return pMessage;
}
default:
JS_ReportError( pContext, "Invalid order type" );
break;
}
return NULL;
}
//-----------------------------------------------------------------------------
// Name: CreatePositionMessage()
// Desc:
//-----------------------------------------------------------------------------
CNetMessage* CNetMessage::CreatePositionMessage(
const CEntityList& entities,
const int type,
CVector2D pos )
{
switch ( type )
{
case NMT_GOTO:
{
CGotoMessage *pMessage = new CGotoMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_TargetX = pos.x;
pMessage->m_TargetY = pos.y;
return pMessage;
}
case NMT_RUN:
{
CRunMessage *pMessage = new CRunMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_TargetX = pos.x;
pMessage->m_TargetY = pos.y;
return pMessage;
}
case NMT_PATROL:
{
CPatrolMessage *pMessage = new CPatrolMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_TargetX = pos.x;
pMessage->m_TargetY = pos.y;
return pMessage;
}
case NMT_ADD_WAYPOINT:
{
CAddWaypointMessage *pMessage = new CAddWaypointMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_TargetX = pos.x;
pMessage->m_TargetY = pos.y;
return pMessage;
}
case NMT_FORMATION_GOTO:
{
CFormationGotoMessage *pMessage = new CFormationGotoMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_TargetX = pos.x;
pMessage->m_TargetY = pos.y;
return pMessage;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Name: CreateEntityIntMessage()
// Desc:
//-----------------------------------------------------------------------------
CNetMessage* CNetMessage::CreateEntityIntMessage(
const CEntityList& entities,
const int type,
HEntity& target,
int action )
{
switch ( type )
{
case NMT_GENERIC:
{
CGenericMessage *pMessage = new CGenericMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_Target = target;
pMessage->m_Action = action;
return pMessage;
}
case NMT_NOTIFY_REQUEST:
{
CNotifyRequestMessage *pMessage = new CNotifyRequestMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_Target = target;
pMessage->m_Action = action;
return pMessage;
}
case NMT_FORMATION_GENERIC:
{
CFormationGenericMessage *pMessage = new CFormationGenericMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_Target = target;
pMessage->m_Action = action;
return pMessage;
}
}
return NULL;
}
CNetMessage* CNetMessage::CreateProduceMessage( const CEntityList& entities, const int type, int proType, const CStrW& name )
{
switch ( type )
{
case NMT_PRODUCE:
{
CProduceMessage* pMessage = new CProduceMessage;
if ( !pMessage ) return NULL;
pMessage->m_Entities = entities;
pMessage->m_Type = proType;
pMessage->m_Name = name;
return pMessage;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Name: CreateMessage()
// Desc: Creates the appropriate message based on the given data
//-----------------------------------------------------------------------------
CNetMessage* CNetMessageFactory::CreateMessage(const void* pData,
size_t dataSize )
{
CNetMessage* pNewMessage = NULL;
CNetMessage header;
// Validate parameters
if ( !pData ) return NULL;
// Figure out message type
header.Deserialize( ( const u8* )pData, ( const u8* )pData + dataSize );
switch ( header.GetType() )
{
case NMT_GAME_SETUP:
pNewMessage = new CGameSetupMessage;
break;
case NMT_ASSIGN_PLAYER_SLOT:
pNewMessage = new CAssignPlayerSlotMessage;
break;
case NMT_PLAYER_CONFIG:
pNewMessage = new CPlayerConfigMessage;
break;
case NMT_PLAYER_JOIN:
pNewMessage = new CPlayerJoinMessage;
break;
case NMT_SERVER_HANDSHAKE:
pNewMessage = new CSrvHandshakeMessage;
break;
case NMT_SERVER_HANDSHAKE_RESPONSE:
pNewMessage = new CSrvHandshakeResponseMessage;
break;
case NMT_CONNECT_COMPLETE:
pNewMessage = new CConnectCompleteMessage;
break;
case NMT_ERROR:
pNewMessage = new CErrorMessage;
break;
case NMT_CLIENT_HANDSHAKE:
pNewMessage = new CCliHandshakeMessage;
break;
case NMT_AUTHENTICATE:
pNewMessage = new CAuthenticateMessage;
break;
case NMT_AUTHENTICATE_RESULT:
pNewMessage = new CAuthenticateResultMessage;
break;
case NMT_GAME_START:
pNewMessage = new CGameStartMessage;
break;
case NMT_END_COMMAND_BATCH:
pNewMessage = new CEndCommandBatchMessage;
break;
}
if ( pNewMessage )
pNewMessage->Deserialize( ( const u8* )pData, ( const u8* )pData + dataSize );
return pNewMessage;
}
//-----------------------------------------------------------------------------
// Name: CreateMessage()
// Desc: Creates a message from the specified JavaScript arguments
//-----------------------------------------------------------------------------
CNetMessage* CNetMessageFactory::CreateMessage(
const CEntityList &entities,
JSContext *pContext,
uintN argc,
jsval *argv,
bool queued )
{
CNetMessage* pNewMessage = NULL;
uint idx = 0;
uint msgType;
// Validate parameters
if ( argv == 0 ) return NULL;
try
{
msgType = ToPrimitive< uint >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid order type" );
return NULL;
}
switch ( msgType )
{
case NMT_GOTO:
{
CGotoMessage *pMessage = new CGotoMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
pNewMessage = pMessage;
}
break;
case NMT_RUN:
{
CRunMessage *pMessage = new CRunMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
pNewMessage = pMessage;
}
break;
case NMT_PATROL:
{
CPatrolMessage *pMessage = new CPatrolMessage;
if ( pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
pNewMessage = pMessage;
}
break;
case NMT_ADD_WAYPOINT:
{
CAddWaypointMessage *pMessage = new CAddWaypointMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
pNewMessage = pMessage;
}
break;
case NMT_FORMATION_GOTO:
{
CFormationGotoMessage *pMessage = new CFormationGotoMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
try
{
if ( idx + 2 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) ||
!JSVAL_IS_INT( argv[ idx + 1 ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_TargetX = ToPrimitive< int >( argv[ idx++ ] );
pMessage->m_TargetY = ToPrimitive< int >( argv[ idx++ ] );
}
catch ( PSERROR_Scripting_ConversionFailed )
{
JS_ReportError( pContext, "Invalid location" );
return NULL;
}
pNewMessage = pMessage;
}
break;
case NMT_GENERIC:
{
CGenericMessage* pMessage = new CGenericMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_OBJECT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
CEntity* pEntity = ToNative< CEntity >( argv[ idx++ ] );
if ( !pEntity )
{
STMT(
JS_ReportError( pContext, "Invalid entity parameter" );
return NULL;
);
}
pMessage->m_Target = pEntity->me;
pNewMessage = pMessage;
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Action = ToPrimitive< int >( argv[ idx++ ] );
break;
}
case NMT_NOTIFY_REQUEST:
{
CNotifyRequestMessage* pMessage = new CNotifyRequestMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_OBJECT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
CEntity* pEntity = ToNative< CEntity >( argv[ idx++ ] );
if ( !pEntity )
{
JS_ReportError( pContext, "Invalid entity parameter" );
return NULL;
}
pMessage->m_Target = pEntity->me;
);
pNewMessage = pMessage;
}
break;
case NMT_FORMATION_GENERIC:
{
CFormationGenericMessage* pMessage = new CFormationGenericMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );\
return NULL;
);
}
if ( !JSVAL_IS_OBJECT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
CEntity* pEntity = ToNative< CEntity >( argv[ idx++ ] );
if ( !pEntity )
{
STMT(
JS_ReportError( pContext, "Invalid entity parameter" );
return NULL;
);
}
pMessage->m_Target = pEntity->me;
);
pNewMessage = pMessage;
}
break;
case NMT_PRODUCE:
{
CProduceMessage* pMessage = new CProduceMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Type = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_STRING( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Name = ToPrimitive< CStrW >( argv[ idx++ ] );
);
pNewMessage = pMessage;
}
break;
case NMT_PLACE_OBJECT:
{
CPlaceObjectMessage* pMessage = new CPlaceObjectMessage;
if ( !pMessage ) return NULL;
pMessage->m_IsQueued = queued;
pMessage->m_Entities = entities;
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_STRING( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Template = ToPrimitive< CStrW >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_X = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Y = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Z = ToPrimitive< int >( argv[ idx++ ] );
);
STMT(
if ( idx + 1 > argc )
{
STMT(
JS_ReportError( pContext, "Too few parameters!" );
return NULL;
);
}
if ( !JSVAL_IS_INT( argv[ idx ] ) )
{
STMT(
JS_ReportError( pContext, "Parameter type error!" );
return NULL;
);
}
pMessage->m_Angle = ToPrimitive< int >( argv[ idx++ ] );
);
pNewMessage = pMessage;
}
break;
default:
JS_ReportError( pContext, "Invalid order type" );
break;
}
return pNewMessage;
}