Exemple #1
0
STAT_TYPE CCharPlayer::Stat_GetLockType( LPCTSTR pszKey ) const
{
	ADDTOCALLSTACK("CCharPlayer::Stat_GetLockType");
	// only players can have skill locks.

	TCHAR szTmpKey[128];
	strcpylen( szTmpKey, pszKey, COUNTOF(szTmpKey) );

	TCHAR * ppArgs[3];
	size_t i = Str_ParseCmds( szTmpKey, ppArgs, COUNTOF(ppArgs), ".[]" );
	if ( i <= 1 )
		return( STAT_NONE );

	if ( IsDigit( ppArgs[1][0] ))
	{
		i = ATOI( ppArgs[1] );
	}
	else
	{
		i = g_Cfg.FindStatKey( ppArgs[1] );
	}
	if ( i >= STAT_BASE_QTY )
		return( STAT_NONE );
	return static_cast<STAT_TYPE>(i);
}
static void StringFunction( int iFunc, LPCTSTR pszKey, CGString &sVal )
{
	GETNONWHITESPACE(pszKey);
	if ( *pszKey == '(' )
		pszKey++;

	TCHAR * ppCmd[4];
	int iCount = Str_ParseCmds( const_cast<TCHAR *>(pszKey), ppCmd, COUNTOF(ppCmd), ",)" );
	if ( ! iCount )
	{
		DEBUG_ERR(( "Bad string function usage. missing )\n" ));
		return;
	}

	TCHAR * psArg1	= ppCmd[0];

	switch ( iFunc )
	{
		case SSC_CHR:
			sVal.Format( "%c", Exp_GetSingle( ppCmd[0] ) );
			return;
		case SSC_StrToLower:	// strlower(str) = lower case the string
			sVal = ppCmd[0];
			sVal.MakeLower();
			return;
		case SSC_StrToUpper:	// strupper(str) = upper case the string
			sVal = ppCmd[0];
			sVal.MakeUpper();
			return;
	}
}
Exemple #3
0
size_t CGRect::Read( LPCTSTR pszVal )
{
	ADDTOCALLSTACK("CGRect::Read");
	// parse reading the rectangle
	TCHAR *pszTemp = Str_GetTemp();
	strcpy( pszTemp, pszVal );
	TCHAR * ppVal[5];
	size_t i = Str_ParseCmds( pszTemp, ppVal, COUNTOF( ppVal ), " ,\t");
	switch (i)
	{
		case 5:
			m_map = ATOI(ppVal[4]);
			if (( m_map < 0 ) || ( m_map >= 256 ) || !g_MapList.m_maps[m_map] )
			{
				g_Log.EventError("Unsupported map #%d specified. Auto-fixing that to 0.\n", m_map);
				m_map = 0;
			}
			m_bottom = ATOI(ppVal[3]);
			m_right = ATOI(ppVal[2]);
			m_top =	ATOI(ppVal[1]);
			m_left = ATOI(ppVal[0]);
			break;
		case 4:
			m_map = 0;
			m_bottom = ATOI(ppVal[3]);
			m_right = ATOI(ppVal[2]);
			m_top =	ATOI(ppVal[1]);
			m_left = ATOI(ppVal[0]);
			break;
		case 3:
			m_map = 0;
			m_bottom = 0;
			m_right = ATOI(ppVal[2]);
			m_top =	ATOI(ppVal[1]);
			m_left = ATOI(ppVal[0]);
			break;
		case 2:
			m_map = 0;
			m_bottom = 0;
			m_right = 0;
			m_top =	ATOI(ppVal[1]);
			m_left = ATOI(ppVal[0]);
			break;
		case 1:
			m_map = 0;
			m_bottom = 0;
			m_right = 0;
			m_top = 0;
			m_left = ATOI(ppVal[0]);
			break;
	}
	NormalizeRect();
	return( i );
}
Exemple #4
0
bool CDialogDef::GumpSetup( int iPage, CClient * pClient, CObjBase * pObjSrc, lpctstr Arguments )
{
    ADDTOCALLSTACK("CDialogDef::GumpSetup");
    CResourceLock	s;

    m_uiControls	= 0;
    m_uiTexts		= 0;
    m_pObj			= pObjSrc;
    m_iOriginX		= 0;
    m_iOriginY		= 0;
    m_wPage			= (word)(iPage);
    m_fNoDispose	= false;

    CScriptTriggerArgs	Args(iPage, 0, pObjSrc);
    //DEBUG_ERR(("Args.m_s1_raw %s  Args.m_s1 %s  Arguments 0x%x\n",Args.m_s1_raw, Args.m_s1, Arguments));
    Args.m_s1_raw = Args.m_s1 = Arguments;

    // read text first
    if ( g_Cfg.ResourceLock( s, CResourceID( RES_DIALOG, GetResourceID().GetResIndex(), RES_DIALOG_TEXT ) ) )
    {
        while ( s.ReadKey())
        {
            if ( m_uiTexts >= (CountOf(m_sText) - 1) )
                break;
            m_pObj->ParseText( s.GetKeyBuffer(), pClient->GetChar() );
            m_sText[m_uiTexts] = s.GetKey();
            m_uiTexts++;
        }
    }
    else
    {
        // no gump text?
    }

    // read the main dialog
    if ( !ResourceLock( s ) )
        return false;
    if ( !s.ReadKey() )		// read the size.
        return false;

    // starting x,y location.
    int64 iSizes[2];
    tchar * pszBuf = s.GetKeyBuffer();
    m_pObj->ParseText( pszBuf, pClient->GetChar() );

    Str_ParseCmds( pszBuf, iSizes, CountOf(iSizes) );
    m_x		= (int)(iSizes[0]);
    m_y		= (int)(iSizes[1]);

    if ( OnTriggerRunVal( s, TRIGRUN_SECTION_TRUE, pClient->GetChar(), &Args ) == TRIGRET_RET_TRUE )
        return false;
    return true;
}
Exemple #5
0
int CSVFile::ReadRowContent(tchar ** ppOutput, int rowIndex, int columns)
{
	ADDTOCALLSTACK("CSVFile::ReadRowContent");
	ASSERT(columns > 0 && columns <= MAX_COLUMNS);
	if ( (int)GetPosition() != rowIndex )
		Seek(rowIndex, SEEK_SET);

	tchar * pszLine = Str_GetTemp();
	if ( ReadString(pszLine, THREAD_STRING_LENGTH) == NULL )
		return 0;

	return Str_ParseCmds(pszLine, ppOutput, columns, "\t");
}
Exemple #6
0
bool CValueCurveDef::Load( TCHAR * pszDef )
{
	ADDTOCALLSTACK("CValueCurveDef::Load");
	// ADV_RATE = Chance at 0, to 100.0
	INT64 Arg_piCmd[101];
	size_t iQty = Str_ParseCmds( pszDef, Arg_piCmd, COUNTOF(Arg_piCmd));
	m_aiValues.SetCount( iQty );
	if ( iQty == 0 )
	{
		return( false );
	}
	for ( size_t i = 0; i < iQty; i++ )
	{
		m_aiValues[i] = static_cast<int>(Arg_piCmd[i]);
	}
	return( true );
}
Exemple #7
0
size_t Str_ParseCmds( TCHAR * pszCmdLine, INT64 * piCmd, size_t iMax, LPCTSTR pszSep )
{
	TCHAR * ppTmp[256];
	if ( iMax > COUNTOF(ppTmp))
		iMax = COUNTOF(ppTmp);

	size_t iQty = Str_ParseCmds( pszCmdLine, ppTmp, iMax, pszSep );
	size_t i;
	for ( i = 0; i < iQty; i++ )
	{
		piCmd[i] = Exp_GetVal(ppTmp[i]);
	}
	for ( ; i < iMax; i++)
	{
		piCmd[i] = 0;
	}
	return( iQty );
}
Exemple #8
0
CTeleport::CTeleport( TCHAR * pszArgs )
{
	// RES_TELEPORT
	// Assume valid iArgs >= 5

	TCHAR * ppCmds[4];
	size_t iArgs = Str_ParseCmds( pszArgs, ppCmds, COUNTOF( ppCmds ), "=" );
	if ( iArgs < 2 )
	{
		DEBUG_ERR(( "Bad CTeleport Def\n" ));
		return;
	}
	Read( ppCmds[0] );
	m_ptDst.Read( ppCmds[1] );
	if ( ppCmds[3] )
		bNpc = (ATOI(ppCmds[3]) != 0);
	else
		bNpc = false;
}
Exemple #9
0
CTeleport::CTeleport(TCHAR *pszArgs)
{
	// RES_TELEPORT
	TCHAR *ppArgs[4];
	size_t iArgQty = Str_ParseCmds(pszArgs, ppArgs, COUNTOF(ppArgs), "=");
	if ( iArgQty < 2 )
		DEBUG_ERR(("Bad teleport def\n"));

	if ( iArgQty >= 1 )
		Read(ppArgs[0]);
	else
		InitPoint();

	if ( iArgQty >= 2 )
		m_ptDst.Read(ppArgs[1]);
	else
		m_ptDst.InitPoint();

	m_fNPC = (iArgQty >= 4) ? (ATOI(ppArgs[3]) != 0) : false;
}
Exemple #10
0
TRIGRET_TYPE CClient::Dialog_OnButton( RESOURCE_ID_BASE rid, DWORD dwButtonID, CObjBase * pObj, CDialogResponseArgs * pArgs )
{
	ADDTOCALLSTACK("CClient::Dialog_OnButton");
	// one of the gump dialog buttons was pressed.
	if ( !pObj )		// object is gone ?
		return TRIGRET_ENDIF;

	CResourceLock s;
	if ( !g_Cfg.ResourceLock(s, RESOURCE_ID(RES_DIALOG, rid.GetResIndex(), RES_DIALOG_BUTTON)) )
		return TRIGRET_ENDIF;

	INT64 piCmd[3];
	while ( s.ReadKeyParse())
	{
		if ( ! s.IsKeyHead( "ON", 2 ))
			continue;

		size_t iArgs = Str_ParseCmds( s.GetArgStr(), piCmd, COUNTOF(piCmd) );
		if ( iArgs == 0 )
			continue;

		if ( iArgs == 1 )
		{
			// single button value
			if ( (DWORD)piCmd[0] != dwButtonID )
				continue;
		}
		else
		{
			// range of button values
			if ( dwButtonID < (DWORD)piCmd[0] || dwButtonID > (DWORD)piCmd[1] )
				continue;
		}

		pArgs->m_iN1	 = dwButtonID;		
		return pObj->OnTriggerRunVal( s, TRIGRUN_SECTION_TRUE, m_pChar, pArgs );
	}

	return( TRIGRET_ENDIF );
}
Exemple #11
0
// only players can have skill locks.
SKILL_TYPE CCharPlayer::Skill_GetLockType( LPCTSTR pszKey ) const
{
	ADDTOCALLSTACK("CCharPlayer::Skill_GetLockType");

	TCHAR szTmpKey[128];
	strcpylen( szTmpKey, pszKey, COUNTOF(szTmpKey) );

	TCHAR * ppArgs[3];
	size_t i = Str_ParseCmds( szTmpKey, ppArgs, COUNTOF(ppArgs), ".[]" );
	if ( i <= 1 )
		return( SKILL_NONE );

	if ( IsDigit( ppArgs[1][0] ))
	{
		i = ATOI( ppArgs[1] );
	}
	else
	{
		i = g_Cfg.FindSkillKey( ppArgs[1] );
	}
	if ( i >= g_Cfg.m_iMaxSkill )
		return( SKILL_NONE );
	return static_cast<SKILL_TYPE>(i);
}
Exemple #12
0
size_t CPointBase::Read( TCHAR * pszVal )
{
	ADDTOCALLSTACK("CPointBase::Read");
	// parse reading the point
	// NOTE: do not use = as a separator here !
	m_z = 0;
	m_map = 0;
	TCHAR * ppVal[4];
	size_t iArgs = Str_ParseCmds( pszVal, ppVal, COUNTOF( ppVal ), " ,\t" );
	switch ( iArgs )
	{
		default:
		case 4:	// m_map
			if ( IsDigit(ppVal[3][0]))
			{
				m_map = static_cast<unsigned char>(ATOI(ppVal[3]));
				if ( !g_MapList.m_maps[m_map] )
				{
					g_Log.EventError("Unsupported map #%d specified. Auto-fixing that to 0.\n", m_map);
					m_map = 0;
				}
			}
		case 3: // m_z
			if ( IsDigit(ppVal[2][0]) || ppVal[2][0] == '-' )
			{
				m_z = static_cast<signed char>(ATOI(ppVal[2]));
			}
		case 2:
			m_y = static_cast<signed short>(ATOI(ppVal[1]));
		case 1:
			m_x = static_cast<signed short>(ATOI(ppVal[0]));
		case 0:
			break;
	}
	return( iArgs );
}
Exemple #13
0
bool CMapList::Load(int map, char *args)
{
	if (( map < 0 ) || ( map > 255 ))
	{
		g_Log.EventError("Invalid map #%d couldn't be initialized.\n", map);
		return false;
	}
	else if ( !m_mapsinitalized[map] )	// disable double intialization
	{
		TCHAR * ppCmd[5];	// maxx,maxy,sectorsize,mapnum[like 0 for map0/statics0/staidx0],mapid
		size_t iCount = Str_ParseCmds(args, ppCmd, COUNTOF(ppCmd), ",");

		if ( iCount <= 0 )	// simple MAPX= same as disabling the map
		{
			m_maps[map] = false;
		}
		else
		{
			int	maxx = 0, maxy = 0, sectorsize = 0, realmapnum = 0, mapid = -1;
			if ( ppCmd[0] ) maxx = ATOI(ppCmd[0]);
			if ( ppCmd[1] ) maxy = ATOI(ppCmd[1]);
			if ( ppCmd[2] ) sectorsize = ATOI(ppCmd[2]);
			if ( ppCmd[3] ) realmapnum = ATOI(ppCmd[3]);
			if ( ppCmd[4] ) mapid = ATOI(ppCmd[4]);

										// zero settings of anything except the real map num means
			if ( maxx )					// skipping the argument
			{
				if (( maxx < 8 ) || ( maxx % 8 ))
				{
					g_Log.EventError("MAP%d: X coord must be multiple of 8 (%d is invalid, %d is still effective).\n", map, maxx, m_sizex[map]);
				}
				else m_sizex[map] = maxx;
			}
			if ( maxy )
			{
				if (( maxy < 8 ) || ( maxy % 8 ))
				{
					g_Log.EventError("MAP%d: Y coord must be multiple of 8 (%d is invalid, %d is still effective).\n", map, maxy, m_sizey[map]);
				}
				else m_sizey[map] = maxy;
			}
			if ( sectorsize > 0 )
			{
				if (( sectorsize < 8 ) || ( sectorsize % 8 ))
				{
					g_Log.EventError("MAP%d: Sector size must be multiple of 8 (%d is invalid, %d is still effective).\n", map, sectorsize, m_sectorsize[map]);
				}
				else if (( m_sizex[map]%sectorsize ) || ( m_sizey[map]%sectorsize ))
				{
					g_Log.EventError("MAP%d: Map dimensions [%d,%d] must be multiple of sector size (%d is invalid, %d is still effective).\n", map, m_sizex[map], m_sizey[map], sectorsize, m_sectorsize[map]);
				}
				else m_sectorsize[map] = sectorsize;
			}
			if ( realmapnum >= 0 )
				m_mapnum[map] = realmapnum;
			if ( mapid >= 0 )
				m_mapid[map] = mapid;
			else
				m_mapid[map] = map;
		}
		m_mapsinitalized[map] = true;
	}
	return true;
}
bool CItemStone::r_Verb( CScript & s, CTextConsole * pSrc ) // Execute command from script
{
	ADDTOCALLSTACK("CItemStone::r_Verb");
	EXC_TRY("Verb");
	// NOTE:: ONLY CALL this from CChar::r_Verb !!!
	// Little to no security checking here !!!

	ASSERT(pSrc);

	int index = FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF(sm_szVerbKeys)-1 );
	if ( index < 0 )
	{
		return( CItem::r_Verb( s, pSrc ));
	}

	CChar * pCharSrc = pSrc->GetChar();
	CStoneMember * pMember = GetMember(pCharSrc);

	switch ( index )
	{
		case ISV_ALLGUILDS:
			{
				if ( s.HasArgs() )
				{
					TCHAR * pszArgs = s.GetArgRaw();
					int iFlags = Exp_GetVal(pszArgs);
					SKIP_ARGSEP(pszArgs);

					if ( iFlags < 0 )
					{
						g_Log.EventError("ItemStone::AllGuilds invalid parameter '%i'.\n", iFlags);
						return false;
					}
					else
					{
						if ( pszArgs[0] != '\0' )
						{
							pMember = STATIC_CAST <CStoneMember *>(GetHead());
							CScript scriptVerb( pszArgs );

							for (; pMember != NULL; pMember = pMember->GetNext())
							{
								if ( pMember->GetLinkUID().IsChar() )
									continue;

								if ( !iFlags )
								{
									pMember->r_Verb(scriptVerb, pSrc);
								}
								else if ( ( iFlags == 1 ) && ( pMember->GetWeDeclared() && !pMember->GetTheyDeclared() ) )
								{
									pMember->r_Verb(scriptVerb, pSrc);
								}
								else if ( ( iFlags == 2 ) && ( !pMember->GetWeDeclared() && pMember->GetTheyDeclared() ) )
								{
									pMember->r_Verb(scriptVerb, pSrc);
								}
								else if ( ( iFlags == 3 ) && ( pMember->GetWeDeclared() && pMember->GetTheyDeclared() ) )
								{
									pMember->r_Verb(scriptVerb, pSrc);
								}
							}
						}
						else
						{
							g_Log.EventError("ItemStone::AllGuilds empty args.\n");
							return false;
						}
					}
				}
			}
			break;
		case ISV_ALLMEMBERS:
			{
				if ( s.HasArgs() )
				{
					TCHAR * pszArgs = s.GetArgRaw();
					int iFlags = Exp_GetVal(pszArgs);
					SKIP_ARGSEP(pszArgs);

					if (( iFlags < -1 ) || ( iFlags > STONEPRIV_ACCEPTED ))
					{
						g_Log.EventError("ItemStone::AllMembers invalid parameter '%i'.\n", iFlags);
						return false;
					}
					else
					{
						if ( pszArgs[0] != '\0' )
						{
							pMember = STATIC_CAST <CStoneMember *>(GetHead());
							CScript scriptVerb( pszArgs );

							for (; pMember != NULL; pMember = pMember->GetNext())
							{
								if ( !pMember->GetLinkUID().IsChar() )
									continue;

								if ( iFlags == -1 )
								{
									pMember->r_Verb(scriptVerb, pSrc);
								}
								else if ( pMember->GetPriv() == static_cast<STONEPRIV_TYPE>(iFlags) )
								{
									pMember->r_Verb(scriptVerb, pSrc);
								}
							}
						}
						else
						{
							g_Log.EventError("ItemStone::AllMembers empty args.\n");
							return false;
						}
					}
				}
			}
			break;
		case ISV_APPLYTOJOIN:
			if ( s.HasArgs())
			{
				CGrayUID pMemberUid = s.GetArgVal();
				CChar * pMemberChar = pMemberUid.CharFind();
				if ( pMemberChar )
				{
					AddRecruit( pMemberChar, STONEPRIV_CANDIDATE );
				}
			}
			break;
		case ISV_CHANGEALIGN:
			if ( s.HasArgs())
			{
				SetAlignType(static_cast<STONEALIGN_TYPE>(s.GetArgVal()));
				TCHAR *pszMsg = Str_GetTemp();
				sprintf(pszMsg, "%s is now a %s %s\n", static_cast<LPCTSTR>(GetName()), static_cast<LPCTSTR>(GetAlignName()), static_cast<LPCTSTR>(GetTypeName()));
				Speak(pszMsg);
			}
			break;
		case ISV_DECLAREPEACE:
			if ( s.HasArgs())
			{
				CGrayUID pMemberUid = s.GetArgVal();
				WeDeclarePeace(pMemberUid);
			}
			break;
		case ISV_DECLAREWAR:
			if ( s.HasArgs())
			{
				CGrayUID pMemberUid = s.GetArgVal();
				CItem * pEnemyItem = pMemberUid.ItemFind();
				if ( pEnemyItem )
				{
					CItemStone * pNewEnemy = dynamic_cast<CItemStone*>(pEnemyItem);
					if ( pNewEnemy )
					{
						WeDeclareWar(pNewEnemy);
					}
				}
			}
			break;
		case ISV_ELECTMASTER:
			ElectMaster();
			break;
		// Need to change FixWeirdness or rewrite how cstonemember guilds are handled.
		case ISV_INVITEWAR:
			{
				if ( s.HasArgs() )
				{
					INT64 piCmd[2];
					size_t iArgQty = Str_ParseCmds( s.GetArgStr(), piCmd, COUNTOF(piCmd));
					if ( iArgQty == 2 )
					{
						CGrayUID pGuildUid = static_cast<unsigned long>(piCmd[0]);
						bool bWeDeclared = (piCmd[1] != 0);
						CItem * pEnemyItem = pGuildUid.ItemFind();
						if ( pEnemyItem && (pEnemyItem->IsType(IT_STONE_GUILD) || pEnemyItem->IsType(IT_STONE_TOWN)) )
						{
							CStoneMember * pMemberGuild = GetMember( pEnemyItem );
							if ( !pMemberGuild )
								pMemberGuild = new CStoneMember(this, pGuildUid, STONEPRIV_ENEMY);

							if ( bWeDeclared )
								pMemberGuild->SetWeDeclared(true);
							else
								pMemberGuild->SetTheyDeclared(true);
						}
					}
				}
			} break;
		case ISV_JOINASMEMBER:
			if ( s.HasArgs())
			{
				CGrayUID pMemberUid = s.GetArgVal();
				CChar * pMemberChar = pMemberUid.CharFind();
				if ( pMemberChar )
				{
					AddRecruit( pMemberChar, STONEPRIV_MEMBER );
				}
			}
			break;
		case ISV_RESIGN:
			if ( s.HasArgs())
			{
				CGrayUID pMemberUid = s.GetArgVal();
				CChar * pMemberChar = pMemberUid.CharFind();
				if ( pMemberChar )
				{
					CStoneMember * pMemberGuild = GetMember( pMemberChar );
					if ( pMemberGuild )
					{
						delete pMemberGuild;
					}
				}
			}
			else
			{
				if ( pMember != NULL )
					delete pMember;
			}
			break;
		case ISV_TOGGLEABBREVIATION:
			{
				CGrayUID pMemberUid = pMember->GetLinkUID();
				if ( s.HasArgs() )
					pMemberUid = s.GetArgVal();
				CChar * pMemberChar = pMemberUid.CharFind();
				if ( pMemberChar )
				{
					CStoneMember * pMemberGuild = GetMember( pMemberChar );
					if ( pMemberGuild )
					{
						pMemberGuild->ToggleAbbrev();
						pMemberChar->ResendTooltip();
					}
				}
			}
			break;
		default:
			return( false );
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPTSRC;
	EXC_DEBUG_END;
	return false;
}
Exemple #15
0
bool CWebPageDef::ServPagePost( CClient * pClient, LPCTSTR pszURLArgs, TCHAR * pContentData, int iContentLength )
{
	ADDTOCALLSTACK("CWebPageDef::ServPagePost");
	UNREFERENCED_PARAMETER(pszURLArgs);
	// RETURN: true = this was the page of interest.

	ASSERT(pClient);

	if ( pContentData == NULL || iContentLength <= 0 )
		return( false );
	if ( ! HasTrigger(XTRIG_UNKNOWN))	// this form has no triggers.
		return( false );

	// Parse the data.
	pContentData[iContentLength] = 0;
	TCHAR * ppArgs[64];
	size_t iArgs = Str_ParseCmds(pContentData, ppArgs, COUNTOF(ppArgs), "&");
	if (( iArgs <= 0 ) || ( iArgs >= 63 ))
		return false;

	// T or TXT or TEXT = the text fields.
	// B or BTN or BUTTON = the buttons
	// C or CHK or CHECK = the check boxes

	CDialogResponseArgs resp;
	DWORD dwButtonID = ULONG_MAX;
	for ( size_t i = 0; i < iArgs; i++ )
	{
		TCHAR * pszNum = ppArgs[i];
		while ( IsAlpha(*pszNum) )
			pszNum++;

		int iNum = ATOI(pszNum);
		while ( *pszNum )
		{
			if ( *pszNum == '=' )
			{
				pszNum++;
				break;
			}
			pszNum++;
		}
		switch ( toupper(ppArgs[i][0]) )
		{
			case 'B':
				dwButtonID = iNum;
				break;
			case 'C':
				if ( !iNum )
					continue;
				if ( ATOI(pszNum) )
				{
					resp.m_CheckArray.Add( iNum );
				}
				break;
			case 'T':
				if ( iNum > 0 )
				{
					TCHAR *pszData = Str_GetTemp();
					HtmlDeCode( pszData, pszNum );
					resp.AddText(static_cast<WORD>(iNum), pszData);
				}
				break;
		}
	}

	// Use the data in RES_WEBPAGE block.
	CResourceLock s;
	if ( !ResourceLock(s) )
		return false;

	// Find the correct entry point.
	while ( s.ReadKeyParse())
	{
		if ( !s.IsKeyHead("ON", 2) || ( (DWORD)s.GetArgVal() != dwButtonID ))
			continue;
		OnTriggerRunVal(s, TRIGRUN_SECTION_TRUE, pClient, &resp);
		return true;
	}

	// Put up some sort of failure page ?

	return( false );
}
bool CItemStone::r_LoadVal( CScript & s ) // Load an item Script
{
	ADDTOCALLSTACK("CItemStone::r_LoadVal");
	EXC_TRY("LoadVal");

	switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		case STC_ABBREV: // "ABBREV"
			m_sAbbrev = s.GetArgStr();
			return true;
		case STC_ALIGN: // "ALIGN"
			SetAlignType(static_cast<STONEALIGN_TYPE>(s.GetArgVal()));
			return true;
		case STC_MasterUid:
			{
				if ( s.HasArgs() )
				{
					CGrayUID pNewMasterUid = (DWORD) s.GetArgVal();
					CChar * pChar = pNewMasterUid.CharFind();
					if ( !pChar )
					{
						DEBUG_ERR(( "MASTERUID called on non char 0%lx uid.\n", (DWORD)pNewMasterUid ));
						return( false );
					}

					CStoneMember * pNewMaster = GetMember( pChar );
					if ( !pNewMaster )
					{
						DEBUG_ERR(( "MASTERUID called on char 0%lx (%s) that is not a valid member of stone with 0x%lx uid.\n", (DWORD)pNewMasterUid, pChar->GetName(), (DWORD)GetUID() ));
						return( false );
					}

					CStoneMember * pMaster = GetMasterMember();
					if ( pMaster )
					{
						if ( pMaster->GetLinkUID() == pNewMasterUid )
							return( true );

						pMaster->SetPriv(STONEPRIV_MEMBER);
						//pMaster->SetLoyalTo(pChar);
					}

					//pNewMaster->SetLoyalTo(pChar);
					pNewMaster->SetPriv(STONEPRIV_MASTER);
				}
				else
				{
					DEBUG_ERR(( "MASTERUID called without arguments.\n" ));
					return( false );
				}
			}
			return( true );
		case STC_MEMBER: // "MEMBER"
			{
			TCHAR *Arg_ppCmd[8];		// Maximum parameters in one line
			size_t Arg_Qty = Str_ParseCmds( s.GetArgStr(), Arg_ppCmd, COUNTOF( Arg_ppCmd ), "," );
			if (Arg_Qty < 1) // must at least provide the member uid
				return false;

			new CStoneMember(
				this,
				ahextoi(Arg_ppCmd[0]),													// Member's UID
				Arg_Qty > 2 ? static_cast<STONEPRIV_TYPE>(ATOI(Arg_ppCmd[2])) : STONEPRIV_CANDIDATE,	// Members priv level (use as a type)
				Arg_Qty > 1 ? Arg_ppCmd[1] : "",										// Title
				ahextoi(Arg_ppCmd[3]),													// Member is loyal to this
				Arg_Qty > 4 ? (ATOI( Arg_ppCmd[4] ) != 0) : 0,							// Paperdoll stone abbreviation (also if they declared war)
				Arg_Qty > 5 ? (ATOI( Arg_ppCmd[5] ) != 0) : 0,							// If we declared war
				Arg_Qty > 6 ? ATOI( Arg_ppCmd[6] ) : 0);								// AccountGold
			}
			return true;
		case STC_WEBPAGE: // "WEBPAGE"
			m_sWebPageURL = s.GetArgStr();
			return true;
	}

	if ( s.IsKeyHead( sm_szLoadKeys[STC_CHARTER], 7 ))
	{
		unsigned int i = ATOI(s.GetKey() + 7);
		if ( i >= COUNTOF(m_sCharter))
			return( false );
		m_sCharter[i] = s.GetArgStr();
		return( true );
	}
	
	return CItem::r_LoadVal(s);
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #17
0
bool CResourceRefArray::r_LoadVal( CScript & s, RES_TYPE restype )
{
	ADDTOCALLSTACK("CResourceRefArray::r_LoadVal");
	EXC_TRY("LoadVal");
	bool fRet = false;
	// A bunch of CResourceLink (CResourceDef) pointers.
	// Add or remove from the list.
	// RETURN: false = it failed.

	// ? "TOWN" and "REGION" are special !

	TCHAR * pszCmd = s.GetArgStr();

	TCHAR * ppBlocks[128];	// max is arbitrary
	size_t iArgCount = Str_ParseCmds( pszCmd, ppBlocks, COUNTOF(ppBlocks));

	for ( size_t i = 0; i < iArgCount; i++ )
	{
		pszCmd = ppBlocks[i];

		if ( pszCmd[0] == '-' )
		{
			// remove a frag or all frags.
			pszCmd ++;
			if ( pszCmd[0] == '0' || pszCmd[0] == '*' )
			{
				RemoveAll();
				fRet = true;
				continue;
			}

			CResourceLink * pResourceLink = dynamic_cast<CResourceLink *>( g_Cfg.ResourceGetDefByName( restype, pszCmd ));
			if ( pResourceLink == NULL )
			{
				fRet = false;
				continue;
			}

			int iIndex = RemovePtr(pResourceLink);
			fRet = ( iIndex >= 0 );
		}
		else
		{
			// Add a single knowledge fragment or appropriate group item.

			if ( pszCmd[0] == '+' ) pszCmd ++;

			CResourceLink * pResourceLink = dynamic_cast<CResourceLink *>( g_Cfg.ResourceGetDefByName( restype, pszCmd ));
			if ( pResourceLink == NULL )
			{
				fRet = false;
				DEBUG_ERR(( "Unknown '%s' Resource '%s'\n", CResourceBase::GetResourceBlockName(restype), pszCmd ));
				continue;
			}

			// Is it already in the list ?
			fRet = true;
			if ( ContainsPtr(pResourceLink) )
			{
				continue;
			}
			if ( g_Cfg.m_pEventsPetLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}
			else if ( g_Cfg.m_pEventsPlayerLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}
			else if ( restype == RES_REGIONTYPE && g_Cfg.m_pEventsRegionLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}
			else if ( g_Cfg.m_iEventsItemLink.ContainsPtr(pResourceLink) )
			{
				DEBUG_ERR(("'%s' already defined in sphere.ini - skipping\n", pResourceLink->GetName()));
				continue;
			}

			Add( pResourceLink );
		}
	}
	return fRet;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #18
0
bool CBaseBaseDef::r_LoadVal( CScript & s )
{
	ADDTOCALLSTACK("CBaseBaseDef::r_LoadVal");
	EXC_TRY("LoadVal");
	if ( s.IsKeyHead( "TAG.", 4 ))
	{
		bool fQuoted = false;
		m_TagDefs.SetStr( s.GetKey()+4, fQuoted, s.GetArgStr( &fQuoted ), false );
		return( true );
	}
	if ( s.IsKeyHead( "TAG0.", 5 ))
	{
		bool fQuoted = false;
		m_TagDefs.SetStr( s.GetKey()+5, fQuoted, s.GetArgStr( &fQuoted ), true );
		return( true );
	}

	switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		//Set as Strings
		case OBC_HITSPELL:
		case OBC_SLAYER:
		case OBC_SLAYERLESSER:
		case OBC_SLAYERMISC:
		case OBC_SLAYERSUPER:
		case OBC_ABILITYPRIMARY:
		case OBC_ABILITYSECONDARY:
		case OBC_MANABURST:
			{
				bool fQuoted = false;
				SetDefStr(s.GetKey(), s.GetArgStr( &fQuoted ), fQuoted);
			}
			break;
		//Set as number only
		case OBC_BALANCED:
		case OBC_BANE:
		case OBC_BATTLELUST:
		case OBC_BLOODDRINKER:
		case OBC_CASTINGFOCUS:
		case OBC_DAMCHAOS:
		case OBC_DAMCOLD:
		case OBC_DAMDIRECT:
		case OBC_DAMENERGY:
		case OBC_DAMFIRE:
		case OBC_DAMMODIFIER:
		case OBC_DAMPHYSICAL:
		case OBC_DECREASEHITCHANCE:
		case OBC_DAMPOISON:
		case OBC_EATERCOLD:
		case OBC_EATERDAM:
		case OBC_EATERENERGY:
		case OBC_EATERFIRE:
		case OBC_EATERKINETIC:
		case OBC_EATERPOISON:
		case OBC_ENHANCEPOTIONS:
		case OBC_EXPANSION:
		case OBC_FASTERCASTING:
		case OBC_FASTERCASTRECOVERY:
		case OBC_HITAREACOLD:
		case OBC_HITAREAENERGY:
		case OBC_HITAREAFIRE:
		case OBC_HITAREAPHYSICAL:
		case OBC_HITAREAPOISON:
		case OBC_HITCURSE:
		case OBC_HITDISPEL:
		case OBC_HITFATIGUE:
		case OBC_HITFIREBALL:
		case OBC_HITHARM:
		case OBC_HITLEECHLIFE:
		case OBC_HITLEECHMANA:
		case OBC_HITLEECHSTAM:
		case OBC_HITLIGHTNING:
		case OBC_HITLOWERATK:
		case OBC_HITLOWERDEF:
		case OBC_HITMAGICARROW:
		case OBC_HITMANADRAIN:
		case OBC_INCREASEDAM:
		case OBC_INCREASEDEFCHANCE:
		case OBC_INCREASEDEFCHANCEMAX:
		case OBC_INCREASEHITCHANCE:
		case OBC_INCREASEGOLD:
		case OBC_INCREASEKARMALOSS:
		case OBC_INCREASESPELLDAM:
		case OBC_INCREASESWINGSPEED:
		case OBC_LOWERAMMOCOST:
		case OBC_LOWERMANACOST:
		case OBC_LOWERREAGENTCOST:
		case OBC_LOWERREQ:
		case OBC_LUCK:
		case OBC_MANABURSTFREQUENCY:
		case OBC_MANABURSTKARMA:
		case OBC_NIGHTSIGHT:
		case OBC_RAGEFOCUS:
		case OBC_REACTIVEPARALYZE:
		case OBC_REFLECTPHYSICALDAM:
		case OBC_REGENFOOD:
		case OBC_REGENHITS:
		case OBC_REGENMANA:
		case OBC_REGENSTAM:
		case OBC_REGENVALFOOD:
		case OBC_REGENVALHITS:
		case OBC_REGENVALMANA:
		case OBC_REGENVALSTAM:
		case OBC_RESCOLD:
		case OBC_RESFIRE:
		case OBC_RESENERGY:
		case OBC_RESPHYSICAL:
		case OBC_RESPOISON:
		case OBC_RESCOLDMAX:
		case OBC_RESFIREMAX:
		case OBC_RESENERGYMAX:
		case OBC_RESPHYSICALMAX:
		case OBC_RESPOISONMAX:
		case OBC_RESONANCECOLD:
		case OBC_RESONANCEENERGY:
		case OBC_RESONANCEFIRE:
		case OBC_RESONANCEKINETIC:
		case OBC_RESONANCEPOISON:
		case OBC_SOULCHARGE:
		case OBC_SOULCHARGECOLD:
		case OBC_SOULCHARGEENERGY:
		case OBC_SOULCHARGEFIRE:
		case OBC_SOULCHARGEKINETIC:
		case OBC_SOULCHARGEPOISON:
		case OBC_SPELLCONSUMPTION:
		case OBC_SPELLFOCUSING:
		case OBC_SPLINTERINGWEAPON:
		case OBC_VELOCITY:
		case OBC_SPELLCHANNELING:
		case OBC_NAMELOC:
		case OBC_HITSPELLSTR:
		case OBC_WEIGHTREDUCTION:
		case OBC_COMBATBONUSSTAT:
		case OBC_COMBATBONUSPERCENT:
			{
				SetDefNum(s.GetKey(),s.GetArgVal());
				return true;
			}
		case OBC_CATEGORY://*
		case OBC_SUBSECTION://*
		case OBC_DESCRIPTION://*
			{
				bool fQuoted = false;
				SetDefStr(s.GetKey(), s.GetArgStr( &fQuoted ), fQuoted);
				if ( !strcmpi(GetDefStr(sm_szLoadKeys[OBC_DESCRIPTION]), "@") )
					SetDefStr(sm_szLoadKeys[OBC_DESCRIPTION], GetDefStr(sm_szLoadKeys[OBC_SUBSECTION]));
			}
			return true;
		case OBC_ARMOR:
			{
				INT64 piVal[2];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piVal, COUNTOF(piVal));
				m_defenseBase = static_cast<unsigned char>(piVal[0]);
				if ( iQty > 1 )
				{
					m_defenseRange = static_cast<unsigned char>(piVal[1]) - m_defenseBase;
				}
				else
				{
					m_defenseRange = 0;
				}
			}
			return( true );
		case OBC_DAM:
			{
				INT64 piVal[2];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piVal, COUNTOF(piVal));
				m_attackBase = static_cast<unsigned char>(piVal[0]);
				if ( iQty > 1 )
				{
					m_attackRange = static_cast<unsigned char>(piVal[1]) - m_attackBase;
				}
				else
				{
					m_attackRange = 0;
				}
			}
			return( true );
		case OBC_BASEID:
			return( false );
		case OBC_CAN:
			m_Can = s.GetArgVal();// | ( m_Can & ( CAN_C_INDOORS|CAN_C_EQUIP|CAN_C_USEHANDS|CAN_C_NONHUMANOID )); //Fixed #2326 ?
			return( true );

		case OBC_DEFNAME:
		case OBC_DEFNAME2:
			return SetResourceName( s.GetArgStr());
		case OBC_HEIGHT:
			m_Height = static_cast<height_t>(s.GetArgVal());
			return( true );
		case OBC_INSTANCES:
			return( false );
		case OBC_NAME:
			SetTypeName( s.GetArgStr());
			return( true );
		case OBC_RANGE:
			{
				INT64 piVal[2];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piVal, COUNTOF(piVal));
				if ( iQty > 1 )
				{
					INT64 iRange = ((piVal[0] & 0xff) << 8) & 0xff00;
					iRange |= (piVal[1] & 0xff);
					SetDefNum(s.GetKey(),iRange, false);
					//m_range	 = ((piVal[0] & 0xff) << 8) & 0xff00;
					//m_range	|= (piVal[1] & 0xff);
				}
				else
				{
					SetDefNum(s.GetKey(),piVal[0], false);
					//m_range	= static_cast<WORD>(piVal[0]);
				}
			}
			return( true );
		case OBC_RESOURCES:
			m_BaseResources.Load( s.GetArgStr());
			return( true );
		case OBC_RESLEVEL:
			return( SetResLevel(static_cast<unsigned char>(s.GetArgVal())) );
		case OBC_RESDISPDNHUE:
			SetResDispDnHue(static_cast<HUE_TYPE>(s.GetArgVal()));
			return( true );
		case OBC_TEVENTS:
			return( m_TEvents.r_LoadVal( s, RES_EVENTS ));
	}
	return( CScriptObj::r_LoadVal(s));
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #19
0
bool CClient::OnRxWebPageRequest( byte * pRequest, size_t iLen )
{
	ADDTOCALLSTACK("CClient::OnRxWebPageRequest");
	// Seems to be a web browser pointing at us ? typical stuff :
	if ( GetConnectType() != CONNECT_HTTP )
		return false;

	// ensure request is null-terminated (if the request is well-formed, we are overwriting a trailing \n here)
	pRequest[iLen - 1] = '\0';

	if ( strlen(reinterpret_cast<char *>(pRequest)) > 1024 )			// too long request
		return false;

	if ( !strpbrk( reinterpret_cast<char *>(pRequest), " \t\012\015" ) )	// malformed request
		return false;

	tchar * ppLines[16];
	size_t iQtyLines = Str_ParseCmds(reinterpret_cast<char *>(pRequest), ppLines, CountOf(ppLines), "\r\n");
	if (( iQtyLines < 1 ) || ( iQtyLines >= 15 ))	// too long request
		return false;

	// Look for what they want to do with the connection.
	bool fKeepAlive = false;
	CSTime dateIfModifiedSince;
	tchar * pszReferer = NULL;
	size_t stContentLength = 0;
	for ( size_t j = 1; j < iQtyLines; j++ )
	{
		tchar	*pszArgs = Str_TrimWhitespace(ppLines[j]);
		if ( !strnicmp(pszArgs, "Connection:", 11 ) )
		{
			pszArgs += 11;
			GETNONWHITESPACE(pszArgs);
			if ( !strnicmp(pszArgs, "Keep-Alive", 10) )
				fKeepAlive = true;
		}
		else if ( !strnicmp(pszArgs, "Referer:", 8) )
		{
			pszReferer = pszArgs+8;
		}
		else if ( !strnicmp(pszArgs, "Content-Length:", 15) )
		{
			pszArgs += 15;
			GETNONWHITESPACE(pszArgs);
			stContentLength = strtoul(pszArgs, NULL, 10);
		}
		else if ( ! strnicmp( pszArgs, "If-Modified-Since:", 18 ))
		{
			// If-Modified-Since: Fri, 17 Dec 1999 14:59:20 GMT\r\n
			pszArgs += 18;
			dateIfModifiedSince.Read(pszArgs);
		}
	}

	tchar * ppRequest[4];
	size_t iQtyArgs = Str_ParseCmds(ppLines[0], ppRequest, CountOf(ppRequest), " ");
	if (( iQtyArgs < 2 ) || ( strlen(ppRequest[1]) >= _MAX_PATH ))
		return false;

	if ( strchr(ppRequest[1], '\r') || strchr(ppRequest[1], 0x0c) )
		return false;

	// if the client hasn't requested a keep alive, we must act as if they had
	// when async networking is used, otherwise data may not be completely sent
	if ( fKeepAlive == false )
	{
		fKeepAlive = m_net->isAsyncMode();

		// must switch to a blocking socket when the connection is not being kept
		// alive, or else pending data will be lost when the socket shuts down

		if ( fKeepAlive == false )
			m_net->m_socket.SetNonBlocking(false);
	}

	linger llinger;
	llinger.l_onoff = 1;
	llinger.l_linger = 500;	// in mSec
	m_net->m_socket.SetSockOpt(SO_LINGER, reinterpret_cast<char *>(&llinger), sizeof(linger));
	char nbool = true;
	m_net->m_socket.SetSockOpt(SO_KEEPALIVE, &nbool, sizeof(char));

	// disable NAGLE algorythm for data compression
	nbool = true;
	m_net->m_socket.SetSockOpt( TCP_NODELAY, &nbool, sizeof(char), IPPROTO_TCP);
	
	if ( memcmp(ppLines[0], "POST", 4) == 0 )
	{
		if ( stContentLength > strlen(ppLines[iQtyLines-1]) )
			return false;

		// POST /--WEBBOT-SELF-- HTTP/1.1
		// Referer: http://127.0.0.1:2593/spherestatus.htm
		// Content-Type: application/x-www-form-urlencoded
		// Host: 127.0.0.1:2593
		// Content-Length: 29
		// T1=stuff1&B1=Submit&T2=stuff2

		g_Log.Event(LOGM_HTTP|LOGL_EVENT, "%x:HTTP Page Post '%s'\n", GetSocketID(), static_cast<lpctstr>(ppRequest[1]));

		CWebPageDef	*pWebPage = g_Cfg.FindWebPage(ppRequest[1]);
		if ( !pWebPage )
			pWebPage = g_Cfg.FindWebPage(pszReferer);
		if ( pWebPage )
		{
			if ( pWebPage->ServPagePost(this, ppRequest[1], ppLines[iQtyLines-1], stContentLength) )
			{
				if ( fKeepAlive )
					return true;
				return false;
			}
			return false;
		}
	}
	else if ( !memcmp(ppLines[0], "GET", 3) )
	{
		// GET /pagename.htm HTTP/1.1\r\n
		// If-Modified-Since: Fri, 17 Dec 1999 14:59:20 GMT\r\n
		// Host: localhost:2593\r\n
		// \r\n

		tchar szPageName[_MAX_PATH];
		if ( !Str_GetBare( szPageName, Str_TrimWhitespace(ppRequest[1]), sizeof(szPageName), "!\"#$%&()*,:;<=>?[]^{|}-+'`" ) )
			return false;

		g_Log.Event(LOGM_HTTP|LOGL_EVENT, "%x:HTTP Page Request '%s', alive=%d\n", GetSocketID(), static_cast<lpctstr>(szPageName), fKeepAlive);
		if ( CWebPageDef::ServPage(this, szPageName, &dateIfModifiedSince) )
		{
			if ( fKeepAlive )
				return true;
			return false;
		}
	}


	return false;
}
TRIGRET_TYPE CScriptObj::OnTriggerForLoop( CScript &s, int iType, CTextConsole * pSrc, CScriptTriggerArgs * pArgs, CGString * pResult )
{
	// loop from start here to the ENDFOR
	// See WebPageScriptList for dealing with Arrays.

	CScriptLineContext StartContext = s.GetContext();
	CScriptLineContext EndContext = StartContext;
	int LoopsMade = 0;

	if ( iType & 8 )		// WHILE
	{
		TCHAR *		pszCond;
		TCHAR		*pszOrig = Str_GetTemp();
		TCHAR		*pszTemp = Str_GetTemp();
		int			iWhile	= 0;

		strcpy( pszOrig, s.GetArgStr() );
		while(true)
		{
			LoopsMade++;
			if ( g_Cfg.m_iMaxLoopTimes && ( LoopsMade >= g_Cfg.m_iMaxLoopTimes ))
				goto toomanyloops;

			pArgs->m_VarsLocal.SetNum( "_WHILE", iWhile, false );
			iWhile++;
			strcpy( pszTemp, pszOrig );
			pszCond	= pszTemp;
			ParseText( pszCond, pSrc, 0, pArgs );
			if ( !Exp_GetVal( pszCond ) )
				break;
			TRIGRET_TYPE iRet = OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult );
			if ( iRet != TRIGRET_ENDIF )
			{
				return( iRet );
			}
			EndContext = s.GetContext();
			s.SeekContext( StartContext );
		}
	}
	else
		ParseText( s.GetArgStr(), pSrc, 0, pArgs );


	
	if ( iType & 4 )		// FOR
	{
		int			fCountDown		= FALSE;
		int			iMin			= 0;
		int			iMax			= 0;
		int			i;
		TCHAR *		ppArgs[3];
		int			iQty			= Str_ParseCmds( s.GetArgStr(), ppArgs, 3, ", " );
		CGString	sLoopVar	= "_FOR";
		
		switch( iQty )
		{
		case 1:		// FOR x
			iMin	= 1;
			iMax	= Exp_GetSingle( ppArgs[0] );
			break;
		case 2:
			if ( isdigit( *ppArgs[0] ) )
			{
				iMin	= Exp_GetSingle( ppArgs[0] );
				iMax	= Exp_GetSingle( ppArgs[1] );
			}
			else
			{
				iMin		= 1;
				iMax		= Exp_GetSingle( ppArgs[1] );
				sLoopVar	= ppArgs[0];
			}
			break;
		case 3:
			sLoopVar	= ppArgs[0];
			iMin		= Exp_GetSingle( ppArgs[1] );;
			iMax		= Exp_GetSingle( ppArgs[2] );
			break;
		default:
			iMin	= iMax		= 1;
			break;
		}

		if ( iMin > iMax )
			fCountDown	= true;

		if ( fCountDown )
			for ( i = iMin; i >= iMax; --i )
			{
				LoopsMade++;
				if ( g_Cfg.m_iMaxLoopTimes && ( LoopsMade >= g_Cfg.m_iMaxLoopTimes ))
					goto toomanyloops;

				pArgs->m_VarsLocal.SetNum( sLoopVar, i, false );
				TRIGRET_TYPE iRet = OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult );
				if ( iRet != TRIGRET_ENDIF )
				{
					return( iRet );
				}
				EndContext = s.GetContext();
				s.SeekContext( StartContext );
			}
		else
			for ( i = iMin; i <= iMax; ++i )
			{
				LoopsMade++;
				if ( g_Cfg.m_iMaxLoopTimes && ( LoopsMade >= g_Cfg.m_iMaxLoopTimes ))
					goto toomanyloops;

				pArgs->m_VarsLocal.SetNum( sLoopVar, i, false );
				TRIGRET_TYPE iRet = OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult );
				if ( iRet != TRIGRET_ENDIF )
				{
					return( iRet );
				}
				EndContext = s.GetContext();
				s.SeekContext( StartContext );
			}
	}

	if ( (iType & 1) || (iType & 2) )
	{
		int iDist;
		if ( s.HasArgs() )
			iDist = s.GetArgVal();
		else
			iDist = UO_MAP_VIEW_SIZE;

		CObjBaseTemplate * pObj = dynamic_cast <CObjBaseTemplate *>(this);
		if ( pObj == NULL )
		{
			iType = 0;
			DEBUG_ERR(( "FOR Loop trigger on non-world object '%s'\n", GetName()));
		}

		CObjBaseTemplate * pObjTop = pObj->GetTopLevelObj();
		CPointMap pt = pObjTop->GetTopPoint();
		if ( iType & 1 )		// FORITEM, FOROBJ
		{
			CWorldSearch AreaItems( pt, iDist );
			while(true)
			{
				LoopsMade++;
				if ( g_Cfg.m_iMaxLoopTimes && ( LoopsMade >= g_Cfg.m_iMaxLoopTimes ))
					goto toomanyloops;

				CItem * pItem = AreaItems.GetItem();
				if ( pItem == NULL )
					break;
				TRIGRET_TYPE iRet = pItem->OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult );
				if ( iRet != TRIGRET_ENDIF )
				{
					return( iRet );
				}
				EndContext = s.GetContext();
				s.SeekContext( StartContext );
			}
		}
		if ( iType & 2 )		// FORCHAR, FOROBJ
		{
			CWorldSearch AreaChars( pt, iDist );
			while(true)
			{
				LoopsMade++;
				if ( g_Cfg.m_iMaxLoopTimes && ( LoopsMade >= g_Cfg.m_iMaxLoopTimes ))
					goto toomanyloops;

				CChar * pChar = AreaChars.GetChar();
				if ( pChar == NULL )
					break;
				if ( ( iType & 0x10 ) && ( ! pChar->IsClient() ) )	// FORCLIENTS
					continue;
				if ( ( iType & 0x20 ) && ( pChar->m_pPlayer == NULL ) )	// FORPLAYERS
					continue;
				TRIGRET_TYPE iRet = pChar->OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult );
				if ( iRet != TRIGRET_ENDIF )
				{
					return( iRet );
				}
				EndContext = s.GetContext();
				s.SeekContext( StartContext );
			}
		}
	}

	if ( g_Cfg.m_iMaxLoopTimes )
	{
toomanyloops:
		if ( LoopsMade >= g_Cfg.m_iMaxLoopTimes )
		{
			g_Log.EventError("Terminating loop cycle since it seems being dead-locked (%d iterations already passed)" DEBUG_CR, LoopsMade);
		}
	}

	if ( EndContext.m_lOffset <= StartContext.m_lOffset )
	{
		// just skip to the end.
		TRIGRET_TYPE iRet = OnTriggerRun( s, TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult );
		if ( iRet != TRIGRET_ENDIF )
		{
			return( iRet );
		}
	}
	else
	{
		s.SeekContext( EndContext );
	}
	return( TRIGRET_ENDIF );
}
Exemple #21
0
bool CGTime::Read( TCHAR * pszVal )
{
	// Read the full date format.

	TCHAR * ppCmds[10];
	int iQty = Str_ParseCmds( pszVal, ppCmds, COUNTOF(ppCmds), "/,: \t" );
	if ( ! iQty )
		return( false );

	struct tm atm;

    atm.tm_wday = 0;    /* days since Sunday - [0,6] */
    atm.tm_yday = 0;    /* days since January 1 - [0,365] */
    atm.tm_isdst = 0;   /* daylight savings time flag */

	if ( isdigit( ppCmds[0][0] ))
	{
		// new format is "1999/8/1 14:30:18"
		if ( iQty < 6 )
		{
			return( false );
		}
		atm.tm_year = atoi( ppCmds[0] ) - 1900;
		atm.tm_mon = atoi( ppCmds[1] ) - 1;
		atm.tm_mday = atoi( ppCmds[2] );
		atm.tm_hour = atoi( ppCmds[3] );
		atm.tm_min = atoi( ppCmds[4] );
		atm.tm_sec = atoi( ppCmds[5] );
	}
	else
	{
		if ( iQty < 7 )
		{
			return( false );
		}

		TCHAR ch = ppCmds[1][0];
		if ( isdigit(ch))
		{
			// or http format is : "Tue, 03 Oct 2000 22:44:56 GMT"
			atm.tm_mday = atoi( ppCmds[1] );
			atm.tm_mon = ReadMonth( ppCmds[2] );
			atm.tm_year = atoi( ppCmds[3] ) - 1900;
			atm.tm_hour = atoi( ppCmds[4] );
			atm.tm_min = atoi( ppCmds[5] );
			atm.tm_sec = atoi( ppCmds[6] );
		}
		else
		{
			// old format is "Tue Mar 30 14:30:18 1999"
			atm.tm_mon = ReadMonth( ppCmds[1] );
			atm.tm_mday = atoi( ppCmds[2] );
			atm.tm_hour = atoi( ppCmds[3] );
			atm.tm_min = atoi( ppCmds[4] );
			atm.tm_sec = atoi( ppCmds[5] );
			atm.tm_year = atoi( ppCmds[6] ) - 1900;
		}
	}

	m_time = mktime(&atm);

	if ( toupper( ppCmds[iQty-1][0] ) == 'G' )
	{
		// convert to GMT
		m_time -= (int)_timezone;
	}
	return( true );
}
TRIGRET_TYPE CScriptObj::OnTriggerRun( CScript &s, TRIGRUN_TYPE trigrun, CTextConsole * pSrc, CScriptTriggerArgs * pArgs, CGString * pResult )
{
	// ARGS:
	//	TRIGRUN_SECTION_SINGLE = just this 1 line.
	// RETURN:
	//  TRIGRET_RET_FALSE = 0 = return and continue processing.
	//  TRIGRET_RET_TRUE = 1 = return and handled. (halt further processing)
	//  TRIGRET_RET_DEFAULT = 2 = if process returns nothing specifically.

	// CScriptFileContext set g_Log.m_pObjectContext is the current context (we assume)
	// DEBUGCHECK( this == g_Log.m_pObjectContext );

	static LPCTSTR const m_ExcKeys[] =
	{
		"parsing",
		"parsing IF statement",
		"parsing begin/loop cycle",
		"foritem",
		"forchar",
		"forclients",
		"forobjs",
		"forplayers",
		"for",
		"while",
		"forcharlayer/memorytype",
		"forcont",
		"forcontid/type",
		"dorand/doswitch",
		"return",
		"CALLing a subfunction",
		"VERBing a value",
	};

	#ifdef WIN32
		EXC_TRY(("OnTriggerRun(%x,%i,%x,%x,%x)", s.GetKey(), trigrun, pSrc, pArgs, pResult));
	#else
		EXC_TRY(("OnTriggerRun(??,%i,%x,%x,%x)", trigrun, pSrc, pArgs, pResult));
	#endif
	
	bool fSectionFalse = (trigrun == TRIGRUN_SECTION_FALSE || trigrun == TRIGRUN_SINGLE_FALSE);
	if ( trigrun == TRIGRUN_SECTION_EXEC || trigrun == TRIGRUN_SINGLE_EXEC )	// header was already read in.
		goto jump_in;

	EXC_SET(m_ExcKeys[0]);
	while ( s.ReadKeyParse())
	{
		// Hit the end of the next trigger.
		if ( s.IsKeyHead( "ON", 2 ))	// done with this section.
			break;

jump_in:
		SK_TYPE iCmd = (SK_TYPE) FindTableSorted( s.GetKey(), sm_szScriptKeys, COUNTOF( sm_szScriptKeys )-1 );
		TRIGRET_TYPE iRet;

		switch ( iCmd )
		{
		case SK_ENDIF:
		case SK_END:
		case SK_ENDDO:
		case SK_ENDFOR:
		case SK_ENDRAND:
		case SK_ENDSWITCH:
		case SK_ENDWHILE:
			return( TRIGRET_ENDIF );

		case SK_ELIF:
		case SK_ELSEIF:
			return( TRIGRET_ELSEIF );

		case SK_ELSE:
			return( TRIGRET_ELSE );
		}

		if ( fSectionFalse )
		{
			// Ignoring this whole section. don't bother parsing it.
			switch ( iCmd )
			{
			case SK_IF:
				EXC_SET(m_ExcKeys[1]);
				do
				{
					iRet = OnTriggerRun( s, TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult );
				} while ( iRet == TRIGRET_ELSEIF || iRet == TRIGRET_ELSE );
				break;
			case SK_WHILE:
			case SK_FOR:
			case SK_FORCHARLAYER:
			case SK_FORCHARMEMORYTYPE:
			case SK_FORCHAR:
			case SK_FORCLIENTS:
			case SK_FORCONT:
			case SK_FORCONTID:
			case SK_FORCONTTYPE:
			case SK_FORITEM:
			case SK_FOROBJ:
			case SK_FORPLAYERS:
			case SK_DORAND:
			case SK_DOSWITCH:
			case SK_BEGIN:
				EXC_SET(m_ExcKeys[2]);
				iRet = OnTriggerRun( s, TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult );
				break;
			}
			if ( trigrun >= TRIGRUN_SINGLE_EXEC )
				return( TRIGRET_RET_DEFAULT );
			continue;	// just ignore it.
		}

		switch ( iCmd )
		{
		case SK_FORITEM:	EXC_SET(m_ExcKeys[3]); iRet = OnTriggerForLoop( s, 1, pSrc, pArgs, pResult );			break;
		case SK_FORCHAR:	EXC_SET(m_ExcKeys[4]); iRet = OnTriggerForLoop( s, 2, pSrc, pArgs, pResult );			break;
		case SK_FORCLIENTS:	EXC_SET(m_ExcKeys[5]); iRet = OnTriggerForLoop( s, 0x12, pSrc, pArgs, pResult );		break;
		case SK_FOROBJ:		EXC_SET(m_ExcKeys[6]); iRet = OnTriggerForLoop( s, 3, pSrc, pArgs, pResult );			break;
		case SK_FORPLAYERS:	EXC_SET(m_ExcKeys[7]); iRet = OnTriggerForLoop( s, 0x22, pSrc, pArgs, pResult );		break;
		case SK_FOR:		EXC_SET(m_ExcKeys[8]); iRet = OnTriggerForLoop( s, 4, pSrc, pArgs, pResult );			break;
		case SK_WHILE:		EXC_SET(m_ExcKeys[9]); iRet = OnTriggerForLoop( s, 8, pSrc, pArgs, pResult );			break;
		case SK_FORCHARLAYER:
		case SK_FORCHARMEMORYTYPE:
			{
				EXC_SET(m_ExcKeys[10]);
				CChar * pCharThis = dynamic_cast <CChar *> (this);
				if ( pCharThis )
				{
					if ( s.HasArgs() )
					{
						if ( iCmd == SK_FORCHARLAYER )
							iRet = pCharThis->OnCharTrigForLayerLoop( s, pSrc, pArgs, pResult, (LAYER_TYPE) s.GetArgVal() );
						else
							iRet = pCharThis->OnCharTrigForMemTypeLoop( s, pSrc, pArgs, pResult, s.GetArgVal() );
						break;
					}
				}
			}
		case SK_FORCONT:
			{
				EXC_SET(m_ExcKeys[11]);
				if ( s.HasArgs() )
				{
					TCHAR * ppArgs[2];
					TCHAR * tempPoint;
					TCHAR 	*porigValue = Str_GetTemp();
					
					int iArgQty = Str_ParseCmds( (TCHAR*) s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), " \t," );
					
					if ( iArgQty >= 1 )
					{
						strcpy(porigValue, ppArgs[0]);
						tempPoint = porigValue;
						ParseText( tempPoint, pSrc, 0, pArgs );
						
						CGrayUID pCurUid = (DWORD) Exp_GetVal(tempPoint);
						if ( pCurUid.IsValidUID() )
						{
							CObjBase * pObj = pCurUid.ObjFind();
							if ( pObj && pObj->IsContainer() )
							{
								CContainer * pContThis = dynamic_cast <CContainer *> (pObj);
								
								CScriptLineContext StartContext = s.GetContext();
								CScriptLineContext EndContext = StartContext;
								iRet = pContThis->OnGenericContTriggerForLoop( s, pSrc, pArgs, pResult, StartContext, EndContext, ppArgs[1] != NULL ? Exp_GetVal(ppArgs[1]) : 255 );
								break;
							}
						}
					}
				}
			}
		case SK_FORCONTID:
		case SK_FORCONTTYPE:
			{
				EXC_SET(m_ExcKeys[12]);
				CContainer * pCont = dynamic_cast <CContainer *> (this);
				if ( pCont )
				{
					if ( s.HasArgs() )
					{
						LPCTSTR pszKey = s.GetArgRaw();
						SKIP_SEPERATORS(pszKey);
					
						TCHAR * ppArgs[2];
						Str_ParseCmds( (TCHAR*) pszKey, ppArgs, COUNTOF(ppArgs), " \t," );

						CScriptLineContext StartContext = s.GetContext();
						CScriptLineContext EndContext = StartContext;
#ifdef _WIN32
						iRet = pCont->OnContTriggerForLoop( s, pSrc, pArgs, pResult, StartContext, EndContext, g_Cfg.ResourceGetID( ( iCmd == SK_FORCONTID ) ? RES_ITEMDEF : RES_TYPEDEF, ppArgs[0] ), 0, ppArgs[1] != NULL ? Exp_GetVal( ppArgs[1] ) : 255 );
#else
						iRet = pCont->OnContTriggerForLoop( s, pSrc, pArgs, pResult, StartContext, EndContext, g_Cfg.ResourceGetID( ( iCmd == SK_FORCONTID ) ? RES_ITEMDEF : RES_TYPEDEF, (const char*&) ppArgs[0] ), 0, ppArgs[1] != NULL ? Exp_GetVal( ppArgs[1] ) : 255 );
#endif
						break;
					}
				}
			}
		default:
			// Parse out any variables in it. (may act like a verb sometimes?)
			EXC_SET(m_ExcKeys[0]);
			ParseText( s.GetArgRaw(), pSrc, 0, pArgs );
		}

		switch ( iCmd )
		{
		case SK_FORITEM:
		case SK_FORCHAR:
		case SK_FORCHARLAYER:
		case SK_FORCHARMEMORYTYPE:
		case SK_FORCLIENTS:
		case SK_FORCONT:
		case SK_FORCONTID:
		case SK_FORCONTTYPE:
		case SK_FOROBJ:
		case SK_FORPLAYERS:
		case SK_FOR:
		case SK_WHILE:
			if ( iRet != TRIGRET_ENDIF )
			{
				if ( iRet > TRIGRET_RET_DEFAULT )
				{
					DEBUG_MSG(( "WARNING: Trigger Bad For Ret %d '%s','%s'\n", iRet, s.GetKey(), s.GetArgStr()));
				}
				return( iRet );
			}
			break;
		case SK_DORAND:	// Do a random line in here.
		case SK_DOSWITCH:
			{
			EXC_SET(m_ExcKeys[13]);
			int iVal = s.GetArgVal();
			if ( iCmd == SK_DORAND )
				iVal = Calc_GetRandVal(iVal);
			for ( ;true; iVal-- )
			{
				iRet = OnTriggerRun( s, (!iVal) ? TRIGRUN_SINGLE_TRUE : TRIGRUN_SINGLE_FALSE, pSrc, pArgs, pResult );
				if ( iRet == TRIGRET_RET_DEFAULT )
					continue;
				if ( iRet == TRIGRET_ENDIF )
					break;
				if ( iRet > TRIGRET_RET_DEFAULT )
				{
					DEBUG_MSG(( "WARNING: Trigger Bad Ret %d '%s','%s'\n", iRet, s.GetKey(), s.GetArgStr()));
				}
				return( iRet );
			}
			}
			break;
		case SK_RETURN:		// Process the trigger.
			EXC_SET(m_ExcKeys[14]);
			if ( pResult )
			{
				pResult->Copy( s.GetArgStr() );
				return (TRIGRET_TYPE) 1;
			}
			return ( (TRIGRET_TYPE) s.GetArgVal() );
		case SK_IF:
			{
				EXC_SET(m_ExcKeys[1]);
				bool fTrigger = s.GetArgVal() ? true : false;
				bool fBeenTrue = false;
				while (true)
				{
					iRet = OnTriggerRun( s, fTrigger ? TRIGRUN_SECTION_TRUE : TRIGRUN_SECTION_FALSE, pSrc, pArgs, pResult );
					if ( iRet < TRIGRET_ENDIF )
						return( iRet );
					if ( iRet == TRIGRET_ENDIF )
						break;
					fBeenTrue |= fTrigger;
					if ( fBeenTrue )
						fTrigger = false;
					else if ( iRet == TRIGRET_ELSE )
						fTrigger = true;
					else if ( iRet == TRIGRET_ELSEIF )
					{
						ParseText( s.GetArgStr(), pSrc, 0, pArgs );
						fTrigger = s.GetArgVal() ? true : false;
					}
				}
			}
			break;

		case SK_BEGIN:
			// Do this block here.
			{
				EXC_SET(m_ExcKeys[2]);
				iRet = OnTriggerRun( s, TRIGRUN_SECTION_TRUE, pSrc, pArgs, pResult );
				if ( iRet != TRIGRET_ENDIF )
				{
					if ( iRet > TRIGRET_RET_DEFAULT )
					{
						DEBUG_MSG(( "WARNING: Trigger Bad Ret %d '%s','%s'\n", iRet, s.GetKey(), s.GetArgStr()));
					}
					return( iRet );
				}
			}
			break;

		default:
			if ( IsSetEF( EF_Scripts_Parse_Verbs ) )
			{
				EXC_SET(m_ExcKeys[0]);
				ParseText( s.GetKeyBuffer(), pSrc, 0, pArgs );
			}
			EXC_SET(m_ExcKeys[0]);
			if ( pArgs && pArgs->r_Verb( s, pSrc ) )
				;
			else
			{
				bool	fRes;
				if ( !strcmpi( (char *)s.GetKey(), "call" ) )
				{
					EXC_SET(m_ExcKeys[15]);
					LPCTSTR	pszArgs	= strchr( s.GetArgRaw(), ' ' );
					if ( pszArgs )
						GETNONWHITESPACE( pszArgs );
					if ( !pszArgs || !*pszArgs )
					{
						fRes	= this->r_Call( s.GetArgRaw(), pSrc, pArgs );
					}
					else
					{
						CScriptTriggerArgs	Args( pszArgs );
						if ( pArgs )
							Args.m_VarsLocal	= pArgs->m_VarsLocal;
						fRes	= this->r_Call( s.GetArgRaw(), pSrc, &Args );
						if ( pArgs )
							pArgs->m_VarsLocal	= Args.m_VarsLocal;
					}
				}
				else
				{
					EXC_SET(m_ExcKeys[16]);
					fRes	= r_Verb( s, pSrc );
				}

				if ( !fRes  )
				{
					DEBUG_MSG(( "WARNING: Trigger Bad Verb '%s','%s'\n", s.GetKey(), s.GetArgStr()));
				}
			}
			break;
		}

		if ( trigrun >= TRIGRUN_SINGLE_EXEC )
			return( TRIGRET_RET_DEFAULT );
	}
	EXC_CATCH("running trigger line");
	return( TRIGRET_RET_DEFAULT );
}
Exemple #23
0
bool CClient::r_Verb(CScript &s, CTextConsole *pSrc) // Execute command from script
{
	ADDTOCALLSTACK("CClient::r_Verb");
	EXC_TRY("Verb");
	// NOTE: This can be called directly from a RES_WEBPAGE script.
	//  So do not assume we are a game client !
	// NOTE: Mostly called from CChar::r_Verb
	// NOTE: Little security here so watch out for dangerous scripts !

	ASSERT(pSrc);
	LPCTSTR pszKey = s.GetKey();

	// Old ver
	if ( s.IsKeyHead("SET", 3) && !g_Cfg.m_Functions.ContainsKey(pszKey) )
	{
		PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel("SET");
		if ( ilevel > GetPrivLevel() )
			return false;

		ASSERT(m_pChar);
		addTargetVerb(pszKey + 3, s.GetArgRaw());
		return true;
	}

	if ( (toupper(pszKey[0]) == 'X') && !g_Cfg.m_Functions.ContainsKey(pszKey) )
	{
		PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel("SET");
		if ( ilevel > GetPrivLevel() )
			return false;

		// Target this command verb on some other object.
		ASSERT(m_pChar);
		addTargetVerb(pszKey + 1, s.GetArgRaw());
		return true;
	}

	int index = FindTableSorted(s.GetKey(), sm_szVerbKeys, COUNTOF(sm_szVerbKeys) - 1);
	switch ( index )
	{
		case CV_ADD:
		{
			if ( s.HasArgs() )
			{
				TCHAR *ppArgs[2];
				size_t iArgQty = Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

				if ( !IsValidGameObjDef(static_cast<LPCTSTR>(ppArgs[0])) )
				{
					g_Log.EventWarn("Invalid ADD argument '%s'\n", ppArgs[0]);
					SysMessageDefault(DEFMSG_CMD_INVALID);
					return true;
				}

				RESOURCE_ID rid = g_Cfg.ResourceGetID(RES_QTY, const_cast<LPCTSTR &>(ppArgs[0]));
				m_tmAdd.m_id = rid.GetResIndex();
				m_tmAdd.m_amount = (iArgQty > 1) ? static_cast<WORD>(maximum(ATOI(ppArgs[1]), 1)) : 1;

				if ( (rid.GetResType() == RES_CHARDEF) || (rid.GetResType() == RES_SPAWN) )
				{
					m_Targ_PrvUID.InitUID();
					return addTargetChars(CLIMODE_TARG_ADDCHAR, static_cast<CREID_TYPE>(m_tmAdd.m_id), false);
				}
				else
					return addTargetItems(CLIMODE_TARG_ADDITEM, static_cast<ITEMID_TYPE>(m_tmAdd.m_id));
				break;
			}

			if ( IsValidDef("d_add") )
				Dialog_Setup(CLIMODE_DIALOG, g_Cfg.ResourceGetIDType(RES_DIALOG, "d_add"), 0, m_pChar);
			else
				Menu_Setup(g_Cfg.ResourceGetIDType(RES_MENU, "MENU_ADDITEM"));
			break;
		}
		case CV_ADDBUFF:
		{
			TCHAR *ppArgs[11];
			Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

			int iArgs[4];
			for ( int i = 0; i < 4; ++i )
			{
				if ( !IsStrNumeric(ppArgs[i]) )
				{
					DEBUG_ERR(("Invalid AddBuff argument number %u\n", i + 1));
					return true;
				}
				iArgs[i] = Exp_GetVal(ppArgs[i]);
			}
			if ( (iArgs[0] < 0) || (iArgs[0] > USHRT_MAX) )
			{
				DEBUG_ERR(("Invalid AddBuff icon ID\n"));
				break;
			}

			LPCTSTR pszArgs[7];
			size_t iArgQty = 0;
			for ( int i = 0; i < 7; ++i )
			{
				pszArgs[i] = ppArgs[i + 4];
				if ( pszArgs[i] != NULL )
					++iArgQty;
			}

			addBuff(static_cast<BUFF_ICONS>(iArgs[0]), static_cast<DWORD>(iArgs[1]), static_cast<DWORD>(iArgs[2]), static_cast<WORD>(iArgs[3]), pszArgs, iArgQty);
			break;
		}
		case CV_REMOVEBUFF:
		{
			BUFF_ICONS IconId = static_cast<BUFF_ICONS>(s.GetArgVal());
			if ( (IconId < 0) || (IconId > USHRT_MAX) )
			{
				DEBUG_ERR(("Invalid RemoveBuff icon ID\n"));
				break;
			}
			removeBuff(IconId);
			break;
		}
		case CV_ADDCLILOC:
		{
			// Add cliloc in @ClientTooltip trigger
			TCHAR *ppArgs[256];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",");
			DWORD dwClilocId = static_cast<DWORD>(Exp_GetLLVal(ppArgs[0]));

			CGString sVal;
			for ( size_t i = 1; i < iArgQty; ++i )
			{
				if ( sVal.GetLength() )
					sVal += "\t";
				sVal += !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i];
			}

			if ( g_Cfg.m_wDebugFlags & DEBUGF_SCRIPTS )
				g_Log.EventDebug("SCRIPT: addcliloc(%lu,'%s')\n", dwClilocId, static_cast<LPCTSTR>(sVal));
			m_TooltipData.Add(new CClientTooltip(dwClilocId, sVal));
			break;
		}
		case CV_ADDCONTEXTENTRY:
		{
			TCHAR *ppArgs[20];
			if ( Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",") > 4 )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: Function takes maximum of 4 arguments!\n"));
				return true;
			}
			if ( !m_pPopupPacket )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: Not used under a @ContextMenuRequest/@itemContextMenuRequest trigger!\n"));
				return true;
			}

			for ( int i = 0; i < 4; ++i )
			{
				if ( (i > 1) && IsStrEmpty(ppArgs[i]) )
					continue;

				if ( !IsStrNumeric(ppArgs[i]) )
				{
					DEBUG_ERR(("Bad AddContextEntry usage: Argument %d must be a number!\n", i + 1));
					return true;
				}
			}

			int iTextEntry = Exp_GetVal(ppArgs[0]);
			if ( iTextEntry < 100 )
			{
				DEBUG_ERR(("Bad AddContextEntry usage: TextEntry < 100 is reserved for server usage!\n"));
				return true;
			}
			m_pPopupPacket->addOption(static_cast<WORD>(iTextEntry), static_cast<DWORD>(Exp_GetLLVal(ppArgs[1])), static_cast<WORD>(Exp_GetLLVal(ppArgs[2])), static_cast<WORD>(Exp_GetLLVal(ppArgs[3])));
			break;
		}
		case CV_ARROWQUEST:
		{
			INT64 piVal[3];
			Str_ParseCmds(s.GetArgRaw(), piVal, COUNTOF(piVal));
			addArrowQuest(static_cast<WORD>(piVal[0]), static_cast<WORD>(piVal[1]), static_cast<DWORD>(piVal[2]));
			break;
		}
		case CV_BADSPAWN:
		{
			// Loop the world searching for bad spawns
			bool fFound = false;
			CItem *pItem = NULL;
			CSector *pSector = NULL;
			CResourceDef *pSpawnDef = NULL;
			for ( int m = 0; (m < 256) && !fFound; ++m )
			{
				if ( !g_MapList.m_maps[m] )
					continue;

				for ( int s = 0; (s < g_MapList.GetSectorQty(m)) && !fFound; ++s )
				{
					pSector = g_World.GetSector(m, s);
					if ( !pSector )
						continue;

					for ( pItem = static_cast<CItem *>(pSector->m_Items_Timer.GetHead()); (pItem != NULL) && !fFound; pItem = pItem->GetNext() )
					{
						if ( pItem->IsType(IT_SPAWN_ITEM) || pItem->IsType(IT_SPAWN_CHAR) )
						{
							pSpawnDef = static_cast<CItemSpawn *>(pItem)->FixDef();
							if ( !pSpawnDef )
							{
								RESOURCE_ID_BASE rid = pItem->IsType(IT_SPAWN_ITEM) ? pItem->m_itSpawnItem.m_ItemID : pItem->m_itSpawnChar.m_CharID;
								CPointMap pt = pItem->GetTopPoint();
								m_pChar->Spell_Teleport(pt, true, false);
								m_pChar->m_Act_Targ = pItem->GetUID();
								SysMessagef("Bad spawn (0%lx, id=%s). Set as ACT", static_cast<DWORD>(pItem->GetUID()), g_Cfg.ResourceGetName(rid));
								fFound = true;
							}
						}
					}
				}
			}
			if ( !fFound )
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NO_BAD_SPAWNS));
			break;
		}
		case CV_BANKSELF:
		{
			addBankOpen(m_pChar, LAYER_BANKBOX);
			break;
		}
		case CV_CAST:
		{
			SPELL_TYPE spell = static_cast<SPELL_TYPE>(g_Cfg.ResourceGetIndexType(RES_SPELL, s.GetArgStr()));
			const CSpellDef *pSpellDef = g_Cfg.GetSpellDef(spell);
			if ( !pSpellDef )
				return true;

			CObjBase *pObjSrc = dynamic_cast<CObjBase *>(pSrc);
			if ( IsSetMagicFlags(MAGICF_PRECAST) && !pSpellDef->IsSpellType(SPELLFLAG_NOPRECAST) )
			{
				int iSkill;
				if ( !pSpellDef->GetPrimarySkill(&iSkill, NULL) )
					return true;

				m_tmSkillMagery.m_Spell = spell;	// m_atMagery.m_Spell
				m_pChar->m_atMagery.m_Spell = spell;
				if ( pObjSrc )
				{
					m_Targ_UID = pObjSrc->GetUID();	// default target.
					m_Targ_PrvUID = pObjSrc->GetUID();
				}
				else
				{
					m_Targ_UID.ClearUID();
					m_Targ_PrvUID.ClearUID();
				}
				m_pChar->Skill_Start(static_cast<SKILL_TYPE>(iSkill));
				break;
			}
			else
				Cmd_Skill_Magery(spell, pObjSrc);
			break;
		}
		case CV_CHANGEFACE:		// open 'face selection' dialog (enhanced clients only)
		{
			addGumpDialog(CLIMODE_DIALOG, NULL, 0, NULL, 0, 0, 0, m_pChar, CLIMODE_DIALOG_FACESELECTION);
			break;
		}
		case CV_CHARLIST:		// usually just a gm command
		{
			if ( !PacketChangeCharacter::CanSendTo(m_NetState) )
				break;
			new PacketChangeCharacter(this);
			CharDisconnect();	// since there is no undoing this in the client.
			SetTargMode(CLIMODE_SETUP_CHARLIST);
			break;
		}
		case CV_CTAGLIST:
		{
			if ( !strcmpi(s.GetArgStr(), "log") )
				pSrc = &g_Serv;
			m_TagDefs.DumpKeys(pSrc, "CTAG.");
			break;
		}
		case CV_CLEARCTAGS:
		{
			if ( s.HasArgs() )
			{
				LPCTSTR pszArgs = s.GetArgStr();
				SKIP_SEPARATORS(pszArgs);
				m_TagDefs.ClearKeys(pszArgs);
			}
			else
				m_TagDefs.ClearKeys();
			break;
		}
		case CV_CLOSEPAPERDOLL:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				closeUIWindow(pChar, 0x1);
			break;
		}
		case CV_CLOSEPROFILE:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				closeUIWindow(pChar, 0x8);
			break;
		}
		case CV_CLOSESTATUS:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				closeUIWindow(pChar, 0x2);
			break;
		}
		case CV_CODEXOFWISDOM:
		{
			INT64 piArgs[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), piArgs, COUNTOF(piArgs));
			if ( iArgQty < 1 )
			{
				SysMessage("Usage: CODEXOFWISDOM TopicID [ForceOpen]");
				break;
			}

			addCodexOfWisdom(static_cast<DWORD>(piArgs[0]), static_cast<bool>(piArgs[1]));
			break;
		}
		case CV_DYE:
		{
			const CObjBase *pObj = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).ObjFind() : NULL;
			if ( pObj )
				addDyeOption(pObj);
			break;
		}
		case CV_EVERBTARG:
		{
			m_Prompt_Text = s.GetArgStr();
			addPromptConsole(CLIMODE_PROMPT_TARG_VERB, m_Targ_Text.IsEmpty() ? "Enter the verb" : "Enter the text", m_Targ_UID);
			break;
		}
		case CV_EXTRACT:
		{
			// sort of like EXPORT but for statics.
			// Opposite of the "UNEXTRACT" command
			TCHAR *ppArgs[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty < 2 )
			{
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_EXTRACT_USAGE));
				break;
			}

			m_Targ_Text = ppArgs[0];				// point at the options (if any)
			m_tmTile.m_ptFirst.InitPoint();			// clear this first
			m_tmTile.m_Code = CV_EXTRACT;			// set extract code
			m_tmTile.m_id = Exp_GetVal(ppArgs[1]);	// extract id
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_EXTRACT_AREA), true);
			break;
		}
		case CV_UNEXTRACT:
		{
			// Create item from script.
			// Opposite of the "EXTRACT" command
			TCHAR *ppArgs[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty < 2 )
			{
				SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_UNEXTRACT_USAGE));
				break;
			}

			m_Targ_Text = ppArgs[0];				// point at the options (if any)
			m_tmTile.m_ptFirst.InitPoint();			// clear this first
			m_tmTile.m_Code = CV_UNEXTRACT;			// set extract code
			m_tmTile.m_id = Exp_GetVal(ppArgs[1]);	// extract id
			addTarget(CLIMODE_TARG_UNEXTRACT, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_MULTI_POS), true);
			break;
		}
		case CV_GMPAGE:
		{
			m_Targ_Text = s.GetArgStr();
			if ( !m_Targ_Text.IsEmpty() && !strnicmp(m_Targ_Text, "ADD ", 4) )
			{
				Cmd_GM_Page(m_Targ_Text + 4);
				break;
			}
			addPromptConsole(CLIMODE_PROMPT_GM_PAGE_TEXT, g_Cfg.GetDefaultMsg(DEFMSG_GMPAGE_PROMPT));
			break;
		}
		case CV_GOTARG:		// go to my (preselected) target.
		{
			ASSERT(m_pChar);
			CObjBase *pObj = m_Targ_UID.ObjFind();
			if ( pObj )
			{
				CPointMap pt = pObj->GetTopLevelObj()->GetTopPoint();
				m_pChar->m_dirFace = m_pChar->GetDir(pObj, m_pChar->m_dirFace);
				m_pChar->Spell_Teleport(pt, true, false);
			}
			break;
		}
		case CV_INFO:
		{
			// We could also get ground tile info.
			addTarget(CLIMODE_TARG_OBJ_INFO, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_ITEM_INFO), true, false);
			break;
		}
		case CV_INFORMATION:
		{
			SysMessage(g_Serv.GetStatusString(0x22));
			SysMessage(g_Serv.GetStatusString(0x24));
			break;
		}
		case CV_LAST:	// fake previous target
		{
			if ( GetTargMode() >= CLIMODE_MOUSE_TYPE )
			{
				ASSERT(m_pChar);
				CObjBase *pObj = m_pChar->m_Act_Targ.ObjFind();
				if ( pObj )
				{
					Event_Target(GetTargMode(), pObj->GetUID(), pObj->GetTopPoint());
					addTargetCancel();
				}
				break;
			}
			return false;
		}
		case CV_LINK:	// link doors
		{
			m_Targ_UID.InitUID();
			addTarget(CLIMODE_TARG_LINK, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_LINK_ITEM));
			break;
		}
		case CV_MAPWAYPOINT:
		{
			INT64 piVal[2];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), piVal, COUNTOF(piVal));
			if ( iArgQty < 2 )
			{
				SysMessage("Usage: MAPWAYPOINT uid type");
				break;
			}
			CObjBase *pObj = static_cast<CGrayUID>(piVal[0]).ObjFind();
			addMapWaypoint(pObj, static_cast<MAPWAYPOINT_TYPE>(piVal[1]));
			break;
		}
		case CV_MENU:
		{
			Menu_Setup(g_Cfg.ResourceGetIDType(RES_MENU, s.GetArgStr()));
			break;
		}
		case CV_MIDILIST:
		{
			INT64 piMidi[64];
			size_t iArgQty = Str_ParseCmds(s.GetArgStr(), piMidi, COUNTOF(piMidi));
			if ( iArgQty > 0 )
				addMusic(static_cast<MIDI_TYPE>(piMidi[Calc_GetRandVal(iArgQty)]));
			break;
		}
		case CV_NUDGE:
		{
			if ( !s.HasArgs() )
			{
				SysMessage("Usage: NUDGE dx dy dz");
				break;
			}
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint();		// clear this first
			m_tmTile.m_Code = CV_NUDGE;
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_NUDGE_AREA), true);
			break;
		}
		case CV_NUKE:
		{
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint();		// clear this first
			m_tmTile.m_Code = CV_NUKE;			// set nuke code
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_NUKE_AREA), true);
			break;
		}
		case CV_NUKECHAR:
		{
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint();		// clear this first
			m_tmTile.m_Code = CV_NUKECHAR;		// set nuke code
			addTarget(CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_NUKE_CHAR_AREA), true);
			break;
		}
		case CV_OPENPAPERDOLL:
		{
			const CChar *pChar = s.HasArgs() ? static_cast<CGrayUID>(s.GetArgVal()).CharFind() : m_pChar;
			if ( pChar )
				addCharPaperdoll(pChar);
			break;
		}
		case CV_OPENTRADEWINDOW:
		{
			TCHAR *ppArgs[2];
			Str_ParseCmds(s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

			CChar *pChar = ppArgs[0] ? static_cast<CGrayUID>(Exp_GetLLVal(ppArgs[0])).CharFind() : NULL;
			if ( pChar )
			{
				CItem *pItem = ppArgs[1] ? static_cast<CGrayUID>(Exp_GetLLVal(ppArgs[1])).ItemFind() : NULL;
				Cmd_SecureTrade(pChar, pItem);
			}
			break;
		}
		case CV_PAGE:
			Cmd_GM_PageCmd(s.GetArgStr());
			break;
		case CV_REPAIR:
			addTarget(CLIMODE_TARG_REPAIR, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_ITEM_REPAIR));
			break;
		case CV_FLUSH:
#ifndef _MTNETWORK
			g_NetworkOut.flush(this);
#else
			g_NetworkManager.flush(m_NetState);
#endif
			break;
		case CV_RESEND:
			addReSync();
			break;
		case CV_SAVE:
			g_World.Save(s.GetArgVal() != 0);
			break;
		case CV_SCROLL:
			// put a scroll up.
			addScrollResource(s.GetArgStr(), SCROLL_TYPE_UPDATES);
			break;
		case CV_SENDPACKET:
			SendPacket(s.GetArgStr());
			break;
		case CV_SELF:		// fake self target
			if ( GetTargMode() >= CLIMODE_MOUSE_TYPE )
			{
				ASSERT(m_pChar);
				Event_Target(GetTargMode(), m_pChar->GetUID(), m_pChar->GetTopPoint());
				addTargetCancel();
				break;
			}
			return false;
		case CV_SHOWSKILLS:
			addSkillWindow(static_cast<SKILL_TYPE>(g_Cfg.m_iMaxSkill));		// reload the real skills
			break;
		case CV_SKILLMENU:
			Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, s.GetArgStr()));
			break;
		case CV_SKILLSELECT:
			Event_Skill_Use(g_Cfg.FindSkillKey(s.GetArgStr()));
			break;
		case CV_SUMMON:
		{
			ASSERT(m_pChar);
			const CSpellDef *pSpellDef = g_Cfg.GetSpellDef(SPELL_Summon);
			if ( !pSpellDef )
				return false;

			m_pChar->m_Act_Targ = m_pChar->GetUID();
			m_pChar->m_Act_TargPrv = m_pChar->GetUID();

			if ( pSpellDef->IsSpellType(SPELLFLAG_TARG_OBJ|SPELLFLAG_TARG_XYZ) )
			{
				m_tmSkillMagery.m_Spell = SPELL_Summon;
				m_tmSkillMagery.m_SummonID = static_cast<CREID_TYPE>(g_Cfg.ResourceGetIndexType(RES_CHARDEF, s.GetArgStr()));

				LPCTSTR pszPrompt = g_Cfg.GetDefaultMsg(DEFMSG_SELECT_MAGIC_TARGET);
				if ( !pSpellDef->m_sTargetPrompt.IsEmpty() )
					pszPrompt = pSpellDef->m_sTargetPrompt;

				int iSpellTimeout = static_cast<int>(GetDefNum("SPELLTIMEOUT"));
				if ( !iSpellTimeout )
					iSpellTimeout = g_Cfg.m_iSpellTimeout * TICK_PER_SEC;

				addTarget(CLIMODE_TARG_SKILL_MAGERY, pszPrompt, pSpellDef->IsSpellType(SPELLFLAG_TARG_XYZ), pSpellDef->IsSpellType(SPELLFLAG_HARM), iSpellTimeout);
				break;
			}
			else
			{
				m_pChar->m_atMagery.m_Spell = SPELL_Summon;
				m_pChar->m_atMagery.m_SummonID = static_cast<CREID_TYPE>(g_Cfg.ResourceGetIndexType(RES_CHARDEF, s.GetArgStr()));

				if ( IsSetMagicFlags(MAGICF_PRECAST) && !pSpellDef->IsSpellType(SPELLFLAG_NOPRECAST) )
				{
					m_pChar->Spell_CastDone();
					break;
				}
				else
				{
					int iSkill;
					if ( !pSpellDef->GetPrimarySkill(&iSkill, NULL) )
						return false;

					m_pChar->Skill_Start(static_cast<SKILL_TYPE>(iSkill));
				}
			}
			break;
		}
		case CV_SMSG:
		case CV_SYSMESSAGE:
			SysMessage(s.GetArgStr());
			break;
		case CV_SYSMESSAGEF:	// there is still an issue with numbers not resolving properly when %i,%d,or other numeric format code is in use
		{
			TCHAR *ppArgs[4];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty < 2 )
			{
				g_Log.EventError("SysMessagef with less than 1 args for the given text\n");
				return false;
			}
			if ( iArgQty > 4 )
			{
				g_Log.EventError("Too many arguments given to SysMessagef (max = text + 3\n");
				return false;
			}
			if ( *ppArgs[0] == '"' )	// skip quotes
				++ppArgs[0];
			for ( TCHAR *pEnd = ppArgs[0] + strlen(ppArgs[0]) - 1; pEnd >= ppArgs[0]; --pEnd )
			{
				if ( *pEnd == '"' )		// skip quotes
				{
					*pEnd = '\0';
					break;
				}
			}
			SysMessagef(ppArgs[0], ppArgs[1], ppArgs[2] ? ppArgs[2] : 0, ppArgs[3] ? ppArgs[3] : 0);
			break;
		}
		case CV_SMSGU:
		case CV_SYSMESSAGEUA:
		{
			TCHAR *ppArgs[5];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs));
			if ( iArgQty > 4 )
			{
				// Font and mode are actually ignored here, but they never made a difference anyway.. I'd like to keep the syntax similar to SAYUA
				NCHAR szBuffer[MAX_TALK_BUFFER];
				CvtSystemToNUNICODE(szBuffer, COUNTOF(szBuffer), ppArgs[4], -1);

				addBarkUNICODE(szBuffer, NULL, static_cast<HUE_TYPE>(Exp_GetLLVal(ppArgs[0])), TALKMODE_SYSTEM, FONT_NORMAL, ppArgs[3]);
			}
			break;
		}
		case CV_SMSGL:
		case CV_SYSMESSAGELOC:
		{
			TCHAR *ppArgs[256];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",");
			if ( iArgQty > 1 )
			{
				HUE_TYPE hue = HUE_TEXT_DEF;
				if ( ATOI(ppArgs[0]) > 0 )
					hue = static_cast<HUE_TYPE>(Exp_GetLLVal(ppArgs[0]));

				DWORD dwClilocId = static_cast<DWORD>(Exp_GetLLVal(ppArgs[1]));

				CGString sVal;
				for ( size_t i = 2; i < iArgQty; ++i )
				{
					if ( sVal.GetLength() )
						sVal += "\t";
					sVal += !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i];
				}

				addBarkLocalized(dwClilocId, NULL, hue, TALKMODE_SYSTEM, FONT_NORMAL, sVal.GetPtr());
			}
			break;
		}
		case CV_SMSGLEX:
		case CV_SYSMESSAGELOCEX:
		{
			TCHAR *ppArgs[256];
			size_t iArgQty = Str_ParseCmds(s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), ",");
			if ( iArgQty > 2 )
			{
				HUE_TYPE hue = HUE_TEXT_DEF;
				AFFIX_TYPE affix = AFFIX_APPEND;
				if ( ATOI(ppArgs[0]) > 0 )
					hue = static_cast<HUE_TYPE>(Exp_GetLLVal(ppArgs[0]));

				DWORD dwClilocId = static_cast<DWORD>(Exp_GetLLVal(ppArgs[1]));

				if ( ppArgs[2] )
					affix = static_cast<AFFIX_TYPE>(Exp_GetLLVal(ppArgs[2]));

				CGString sVal;
				for ( size_t i = 4; i < iArgQty; ++i )
				{
					if ( sVal.GetLength() )
						sVal += "\t";
					sVal += !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i];
				}

				addBarkLocalizedEx(dwClilocId, NULL, hue, TALKMODE_SYSTEM, FONT_NORMAL, affix, ppArgs[3], sVal.GetPtr());
			}
			break;
		}
		case CV_TELE:
			Cmd_Skill_Magery(SPELL_Teleport, dynamic_cast<CObjBase *>(pSrc));
			break;
		case CV_TILE:
			if ( !s.HasArgs() )
			{
				SysMessage("Usage: TILE z-height item1 item2 itemX");
				break;
			}
			m_Targ_Text = s.GetArgStr();	// point at the options
			m_tmTile.m_ptFirst.InitPoint();	// clear this first
			m_tmTile.m_Code = CV_TILE;
			addTarget(CLIMODE_TARG_TILE, "Pick 1st corner:", true);
			break;
		case CV_VERSION:
			SysMessage(g_szServerDescription);
			break;
		case CV_WEBLINK:
			addWebLaunch(s.GetArgStr());
			break;
		default:
			if ( r_LoadVal(s) )
			{
				CGString sVal;
				if ( r_WriteVal(s.GetKey(), sVal, pSrc) )
					return true;
			}
			return CScriptObj::r_Verb(s, pSrc);		// used in the case of web pages to access server level things
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPTSRC;
	EXC_DEBUG_END;
	return false;
}
bool CScriptObj::r_Verb( CScript & s, CTextConsole * pSrc ) // Execute command from script
{
	LOCKDATA;
	EXC_TRY(("r_Verb('%s %s',%x)", s.GetKey(), s.GetArgStr(), pSrc));
	int	index;
	LPCTSTR pszKey = s.GetKey();

	ASSERT( pSrc );
	CScriptObj * pRef;

	if ( r_GetRef( pszKey, pRef ))
	{
		if ( pszKey[0] )
		{
			if ( !pRef ) return true;
			CScript script( pszKey, s.GetArgStr());
			return pRef->r_Verb( script, pSrc );
		}
		// else just fall through. as they seem to be setting the pointer !?
	}

	if ( s.IsKeyHead( "SRC.", 4 ))
	{
		pszKey += 4;
		pRef = dynamic_cast <CScriptObj*> (pSrc->GetChar());	// if it can be converted .
		if ( ! pRef )
		{
			pRef = dynamic_cast <CScriptObj*> (pSrc);
			if ( ! pRef )
				return( false );
		}
		CScript script( pszKey, s.GetArgStr());
		return pRef->r_Verb( script, pSrc );
	}

	index = FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF( sm_szVerbKeys )-1 );
	switch (index)
	{
	case SSV_OBJ:
		g_World.m_uidObj = s.GetArgVal();
		if ( !g_World.m_uidObj.ObjFind() ) g_World.m_uidObj = 0;
		return( true );
	case SSV_NEW:
		g_World.m_uidNew = s.GetArgVal();
		if ( !g_World.m_uidNew.ObjFind() ) g_World.m_uidNew = 0;
		return( true );
	case SSV_DUMPKEYS:
		r_DumpLoadKeys( pSrc );
		return( true );
	case SSV_DUMPVERBS:
		r_DumpVerbKeys( pSrc );
		return( true );
	case SSV_SHOW:
		{
			CGString sVal;
			if ( ! r_WriteVal( s.GetArgStr(), sVal, pSrc ))
				return( false );
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, "'%s' for '%s' is '%s'\n", (LPCTSTR) s.GetArgStr(), (LPCTSTR) GetName(), (LPCTSTR) sVal );
			pSrc->SysMessage(pszMsg);
		}
		return( true );
	case SSV_TRIGGER:
		{
		// This is effectively a goto to an alternate trigger. (for this same object)
		TCHAR * pszVals[2];
		// CScriptTriggerArgs * pArgs = NULL ?
		if ( Str_ParseCmds( s.GetArgStr(), pszVals, COUNTOF(pszVals)))
		{
			TRIGRET_TYPE tRet = OnTrigger( pszVals[0], pSrc, NULL );
			return( true );
		}
		}
		return( false );
	}
	return r_LoadVal( s );	// default to loading values.
	EXC_CATCH("CScriptObj");
	return false;
}
bool CScriptObj::r_WriteVal( LPCTSTR pszKey, CGString &sVal, CTextConsole * pSrc )
{
	EXC_TRY(("r_WriteVal('%s',,%x)", pszKey, pSrc));
	CScriptObj * pRef;
	if ( r_GetRef( pszKey, pRef ))
	{
		if ( pRef == NULL )	// good command but bad link.
		{
			sVal = "0";
			return true;
		}
		if ( pszKey[0] == '\0' )	// we where just testing the ref.
		{
			CObjBase *	pObj	= dynamic_cast <CObjBase *> (pRef);
			if ( pObj )
				sVal.FormatHex( (DWORD) pObj->GetUID() );
			else
				sVal.FormatVal( 1 );
			return( true );
		}
		return pRef->r_WriteVal( pszKey, sVal, pSrc );
	}

	int i = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 );
	if ( i < 0 )
	{
		// <dSOMEVAL> same as <eval <SOMEVAL>> to get dec from the val
		if (( *pszKey == 'd' ) || ( *pszKey == 'D' ))
		{
			LPCTSTR arg = pszKey + 1;
			if ( r_WriteVal(arg, sVal, pSrc) )
			{
				if ( !IsStrNumericDec(sVal) ) // dValue dec -> hex fix
				{
					sVal.FormatVal(ahextoi(sVal));
				}
				return true;
			}
		}
		// <r>, <r15>, <r3,15> are shortcuts to rand(), rand(15) and rand(3,15)
		else if (( *pszKey == 'r' ) || ( *pszKey == 'R' ))
		{
			char	*zTemp = Str_GetTemp();
			strcpy(zTemp, pszKey+1);

			if (( *zTemp ) &&  (( *zTemp < '0' ) || ( *zTemp > '9' )) )
				goto badcmd;

			TCHAR	*ppCmd[2];
			int		qty = Str_ParseCmds(zTemp, ppCmd, COUNTOF(ppCmd));
			int		min = 0, max = 1000;

			if ( qty == 1 ) max = atoi(ppCmd[0]);
			else if ( qty == 2 )
			{
				min = g_Exp.GetVal(ppCmd[0]);
				max = g_Exp.GetVal(ppCmd[1]);
			}

			if ( min > max )
			{
				int a = min;
				min = max;
				max = a;
			}
			if ( min == max )
				sVal.FormatVal(min);
			else
				sVal.FormatVal(min + Calc_GetRandVal(max - min));

			return true;
		}
badcmd:
		return false;	// Bad command.
	}

	pszKey += strlen( sm_szLoadKeys[i] );
	SKIP_SEPERATORS(pszKey);
	bool	fZero	= false;

	switch ( i )
	{
	case SSC_LISTCOL:
		// Set the alternating color.
		sVal = (CWebPageDef::sm_iListIndex&1) ? "bgcolor=\"#E8E8E8\"" : "";
		return( true );
	case SSC_OBJ:
		if ( !g_World.m_uidObj.ObjFind() ) g_World.m_uidObj = 0;
		sVal.FormatHex((DWORD)g_World.m_uidObj);
		return true;
	case SSC_NEW:
		if ( !g_World.m_uidNew.ObjFind() ) g_World.m_uidNew = 0;
		sVal.FormatHex((DWORD)g_World.m_uidNew);
		return true;
	case SSC_SRC:
		if ( pSrc == NULL )
			pRef	= NULL;
		else
		{
			pRef = pSrc->GetChar();	// if it can be converted .
			if ( ! pRef )
				pRef = dynamic_cast <CScriptObj*> (pSrc);	// if it can be converted .
		}
		if ( ! pRef )
		{
			sVal.FormatVal( 0 );
			return true;
		}
		if ( !*pszKey )
		{
			CObjBase * pObj = dynamic_cast <CObjBase*> (pRef);	// if it can be converted .
			sVal.FormatHex( pObj ? (DWORD) pObj->GetUID() : 0 );
			return true;
		}
		return pRef->r_WriteVal( pszKey, sVal, pSrc );
	case SSC_VAR0:
		fZero	= true;
	case SSC_VAR:
		// "VAR." = get/set a system wide variable.
		{
			CVarDefBase * pVar = g_Exp.m_VarGlobals.GetKey(pszKey);
			if ( pVar )
				sVal	= pVar->GetValStr();
			else if ( fZero )
				sVal	= "0";
		}
		return true;
	case SSC_DEF0:
		fZero	= true;
	case SSC_DEF:
		{
			CVarDefBase * pVar = g_Exp.m_VarDefs.GetKey(pszKey);
			if ( pVar )
				sVal	= pVar->GetValStr();
			else if ( fZero )
				sVal	= "0";
		}
		return( true );
	case SSC_EVAL:
		sVal.FormatVal( Exp_GetVal( pszKey ));
		return( true );
	case SSC_FVAL:
		{
		int	iVal		= Exp_GetVal( pszKey );
		sVal.Format( "%i.%i", iVal/10, abs(iVal%10) );
		return true;
		}
	case SSC_HVAL:
		sVal.FormatHex( Exp_GetVal( pszKey ));
		return( true );
	case SSC_QVAL:
		{	// Do a switch ? type statement <QVAL conditional ? option1 : option2>
			TCHAR * ppCmds[3];
			ppCmds[0] = const_cast<TCHAR*>(pszKey);
			Str_Parse( ppCmds[0], &(ppCmds[1]), "?" );
			Str_Parse( ppCmds[1], &(ppCmds[2]), ":" );
			sVal = ppCmds[ Exp_GetVal( ppCmds[0] ) ? 1 : 2 ];
			if ( sVal.IsEmpty())
				sVal = " ";
		}
		return( true );
	case SSC_ISEMPTY:
		sVal.FormatVal( IsStrEmpty( pszKey ) );
		return true;
	case SSC_ISNUM:
		GETNONWHITESPACE( pszKey );
		sVal.FormatVal( IsStrNumeric( pszKey ) );
		return true;
	case SSC_StrRev:
		{
			GETNONWHITESPACE( pszKey );
			sVal = pszKey;
			sVal.Reverse();
			return true;
		}
	case SSC_StrPos:
		{
			GETNONWHITESPACE( pszKey );
			int	iPos	= Exp_GetVal( pszKey );
			TCHAR	ch;
			if ( isdigit( *pszKey) && isdigit( *(pszKey+1) ) )
				ch	= (TCHAR) Exp_GetVal( pszKey );
			else
			{
				ch	= *pszKey;
				pszKey++;
			}
			
			GETNONWHITESPACE( pszKey );
			int	iLen	= strlen( pszKey );
			if ( iPos < 0 )
				iPos	= iLen + iPos;
			if ( iPos < 0 )
				iPos	= 0;
			else if ( iPos > iLen )
				iPos	= iLen;

			TCHAR *	pszPos	= strchr( pszKey + iPos, ch );
			if ( !pszPos )
				sVal.FormatVal( -1 );
			else
				sVal.FormatVal( pszPos - pszKey );
		}
		return true;
	case SSC_StrSub:
		{
			int	iPos	= Exp_GetVal( pszKey );
			int	iCnt	= Exp_GetVal( pszKey );
			SKIP_ARGSEP( pszKey );
			GETNONWHITESPACE( pszKey );

			int	iLen	= strlen( pszKey );
			if ( iPos < 0 ) iPos += iLen;
			if ( iPos > iLen || iPos < 0 ) iPos = 0;

			if ( iPos + iCnt > iLen || iCnt == 0 )
				iCnt = iLen - iPos;

			TCHAR	*buf = Str_GetTemp();
			strncpy( buf, pszKey + iPos, iCnt );
			buf[iCnt] = '\0';
			sVal = buf;
		}
		return true;
	case SSC_StrArg:
		{
			TCHAR	*buf = Str_GetTemp();
			GETNONWHITESPACE( pszKey );
			if ( *pszKey == '"' )
				pszKey++;
			int	i	= 0;
			while ( *pszKey && !isspace( *pszKey ) && *pszKey != ',' )
			{
				buf[i]	= *pszKey;
				pszKey++;
				i++;
			}
			buf[i]	= '\0';
			sVal	= buf;
		}
		return true;
	case SSC_StrEat:
		{
			GETNONWHITESPACE( pszKey );
			while ( *pszKey && !isspace( *pszKey ) && *pszKey != ',' )
				pszKey++;
			SKIP_ARGSEP( pszKey );
			sVal	= pszKey;
		}
		return true;
	case SSC_ASC:
		{
			TCHAR	*buf = Str_GetTemp();
			REMOVE_QUOTES( pszKey );
			sVal.FormatHex( *pszKey );
			sprintf( buf, sVal );
			while ( *(++pszKey) )
			{
				if ( *pszKey == '"' ) break;
				sVal.FormatHex( *pszKey );
				strcat( buf, " " );
				strcat( buf, sVal );
			}
			sVal	= buf;
		}
		return true;

	case SSC_READFILE:
		{
			if ( !IsSetOF( OF_FileCommands ) ) 
				return false;

			TCHAR	*rfArgs[1];
			FILE	*rfFD;
			TCHAR	*buf = Str_GetTemp();

			int line;

			rfArgs[0] = const_cast<TCHAR*>(pszKey);
			Str_Parse( rfArgs[0], &(rfArgs[1]), " " );

			// Remove other junk
			Str_Parse( rfArgs[1], NULL, " " );

			line = atoi( rfArgs[1] );

			sVal = "";
			if ( rfFD = fopen( rfArgs[0], "r" ))
			{
				if ( line == -1 )	// First line of the file
					fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
				else if ( line == 0 )
				{
					// Last line of the file
					while ( ! feof( rfFD ) )
						fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
				}					
				else
				{
					// Line "line" of the file
					int x;
					for ( x = 1; x <= line; x++ )
					{
						if ( feof(rfFD) )
						{
							buf[0] = 0;
							break;
						}
						fgets(buf, SCRIPT_MAX_LINE_LEN, rfFD );
					}
				}
				sVal = buf;
				fclose(rfFD);
			}
		}
		return true;
	case SSC_FILELINES:
		{
			if ( !IsSetOF( OF_FileCommands ) )
				return false;
			
			TCHAR	*buf = Str_GetTemp();
			FILE	*flFD;
			int		x(0);
			GETNONWHITESPACE( pszKey );
			if ( flFD = fopen( pszKey, "r" ) )
			{
				while ( ! feof(flFD) )
				{
					fgets(buf, SCRIPT_MAX_LINE_LEN, flFD );
					x++;
				}
				fclose(flFD);
			}
			sVal.FormatVal(x);
		}
		return true;
	case SSC_SYSCMD:
	case SSC_SYSSPAWN:
		{
			if ( !IsSetOF(OF_FileCommands) )
				return false;

			GETNONWHITESPACE(pszKey);
			TCHAR	*buf = Str_GetTemp();
			TCHAR	*Arg_ppCmd[10];		// limit to 9 arguments
			strcpy(buf, pszKey);
			int iQty = Str_ParseCmds(buf, Arg_ppCmd, COUNTOF(Arg_ppCmd));
			if ( iQty < 1 )
				return false;

#ifdef WIN32
			_spawnl(
				( i == SSC_SYSCMD ) ? _P_WAIT : _P_NOWAIT,
				Arg_ppCmd[0],
				Arg_ppCmd[0],
				Arg_ppCmd[1],
				Arg_ppCmd[2],
				Arg_ppCmd[3],
				Arg_ppCmd[4],
				Arg_ppCmd[5],
				Arg_ppCmd[6],
				Arg_ppCmd[7],
				Arg_ppCmd[8],
				Arg_ppCmd[9],
				NULL
			);
#else
			g_Log.EventError("sysspawn/syscmd is not available on unix builds." DEBUG_CR);
#endif
			return true;
		}

	default:
		StringFunction( i, pszKey, sVal );
		return true;
	}
	EXC_CATCH("CScriptObj");
	return false;
}
Exemple #26
0
/////////////////////////////////////////////////////////////////////////////////////
//
//	FUNCTION: main()
//
/////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);

	TCHAR	*argv[32];
	argv[0] = NULL;
	int argc = Str_ParseCmds(lpCmdLine, &argv[1], COUNTOF(argv)-1, " \t") + 1;

	if ( GRAY_GetOSInfo()->dwPlatformId != VER_PLATFORM_WIN32_NT )
	{
		// We are running Win9x - So we are not an NT service.
do_not_nt_service:
		NTWindow_Init(hInstance, lpCmdLine, nCmdShow);
		int iRet = Sphere_MainEntryPoint(argc, argv);
		NTWindow_Exit();
		TerminateProcess(GetCurrentProcess(), iRet);
		return iRet;
	}

	// We need to find out what the server name is....look it up in the .ini file
	if ( !g_Cfg.LoadIni(true) )
	{
		// Try to determine the name and path of this application.
		char szPath[_MAX_PATH];

		GetModuleFileName(NULL, szPath, sizeof(szPath));

		if ( !szPath[0] )
			return -2;

		ExtractPath(szPath);
		g_Cfg.LoadIni(false);
	}

	if ( !g_Cfg.m_fUseNTService )	// since there is no way to detect how did we start, use config for that
		goto do_not_nt_service;

	g_Service.SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 5000);

	// process the command line arguments...
	if (( argc > 1 ) && _IS_SWITCH(*argv[1]) )
	{
		if ( argv[1][1] == 'k' )		// service control
		{
			if ( argc < 3 )
			{
				printf("Use \"-k command\" with operation to proceed (install/remove)\n");
			}
			else if ( !strcmp(argv[2], "install") )
			{
				g_Service.CmdInstallService();
			}
			else if ( !strcmp(argv[2], "remove") )
			{
				g_Service.CmdRemoveService();
			}
			return 0;
		}
	}

	// If the argument does not match any of the above parameters, the Service Control Manager (SCM) may
	// be attempting to start the service, so we must call StartServiceCtrlDispatcher.
	g_Service.ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "Starting Service.");

	g_Service.CmdMainStart();
	g_Service.SetServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
	return -1;
}
Exemple #27
0
bool CCharNPC::r_LoadVal( CChar * pChar, CScript &s )
{
	EXC_TRY("LoadVal");
	switch ( FindTableSorted( s.GetKey(), sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
	//Set as Strings
	case CNC_THROWDAM:
	case CNC_THROWOBJ:
	case CNC_THROWRANGE:
		{
			bool fQuoted = false;
			pChar->SetDefStr(s.GetKey(), s.GetArgStr( &fQuoted ), fQuoted);
		}
		break;
	//Set as numbers only
	case CNC_BONDED:
		m_bonded = (s.GetArgVal() > 0);
		break;
	case CNC_FOLLOWERSLOTS:
		pChar->SetDefNum(s.GetKey(), s.GetArgVal(), false );
		break;
	case CNC_ACTPRI:
		m_Act_Motivation = static_cast<unsigned char>(s.GetArgVal());
		break;
	case CNC_NPC:
		m_Brain = static_cast<NPCBRAIN_TYPE>(s.GetArgVal());
		break;
	case CNC_HOMEDIST:
		if ( ! pChar->m_ptHome.IsValidPoint())
		{
			pChar->m_ptHome = pChar->GetTopPoint();
		}
		m_Home_Dist_Wander = static_cast<WORD>(s.GetArgVal());
		break;
	case CNC_NEED:
	case CNC_NEEDNAME:
		{
			TCHAR * pTmp = s.GetArgRaw();
			m_Need.Load(pTmp);
		}
		break;
	case CNC_SPEECH:
		return( m_Speech.r_LoadVal( s, RES_SPEECH ));
	case CNC_SPEECHCOLOR:
		m_SpeechHue = static_cast<HUE_TYPE>(s.GetArgVal());
		break;

	case CNC_VENDCAP:
		{
			CItemContainer * pBank = pChar->GetBank();
			if ( pBank )
				pBank->m_itEqBankBox.m_Check_Restock = s.GetArgVal();
		}
		break;
	case CNC_VENDGOLD:
		{
			CItemContainer * pBank = pChar->GetBank();
			if ( pBank )
				pBank->m_itEqBankBox.m_Check_Amount = s.GetArgVal();
		}
		break;
	case CNC_SPELLADD:
	{
		INT64 ppCmd[255];
		size_t count = Str_ParseCmds(s.GetArgStr(), ppCmd, COUNTOF(ppCmd));
		if (count < 1)
			return false;
		for (size_t i = 0; i < count; i++)
			Spells_Add(static_cast<SPELL_TYPE>(ppCmd[i]));
	}

	default:
		// Just ignore any player type stuff.
		if ( FindTableHeadSorted( s.GetKey(), CCharPlayer::sm_szLoadKeys, COUNTOF( CCharPlayer::sm_szLoadKeys )-1 ) >= 0 )
			return( true );
		return(false );
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #28
0
bool CBaseBaseDef::r_LoadVal(CScript &s)
{
	ADDTOCALLSTACK("CBaseBaseDef::r_LoadVal");
	EXC_TRY("LoadVal");
	if ( s.IsKeyHead("TAG.", 4) )
	{
		bool fQuoted = false;
		m_TagDefs.SetStr(s.GetKey() + 4, fQuoted, s.GetArgStr(&fQuoted), false);
		return true;
	}
	if ( s.IsKeyHead("TAG0.", 5) )
	{
		bool fQuoted = false;
		m_TagDefs.SetStr(s.GetKey() + 5, fQuoted, s.GetArgStr(&fQuoted), true);
		return true;
	}

	switch ( FindTableSorted(s.GetKey(), sm_szLoadKeys, COUNTOF(sm_szLoadKeys) - 1) )
	{
		// Set as numeric
		case OBC_COMBATBONUSPERCENT:
		case OBC_COMBATBONUSSTAT:
		case OBC_DAMCHAOS:
		case OBC_DAMDIRECT:
		case OBC_EXPANSION:
		case OBC_NAMELOC:
		case OBC_REGENFOOD:
		case OBC_REGENHITS:
		case OBC_REGENMANA:
		case OBC_REGENSTAM:
		case OBC_REGENVALFOOD:
		case OBC_REGENVALHITS:
		case OBC_REGENVALMANA:
		case OBC_REGENVALSTAM:
		{
			SetDefNum(s.GetKey(), s.GetArgVal());
			return true;
		}
		case OBC_CATEGORY:
		case OBC_SUBSECTION:
		case OBC_DESCRIPTION:
		{
			bool fQuoted = false;
			SetDefStr(s.GetKey(), s.GetArgStr(&fQuoted), fQuoted);
			if ( !strcmpi(GetDefStr(sm_szLoadKeys[OBC_DESCRIPTION]), "@") )
				SetDefStr(sm_szLoadKeys[OBC_DESCRIPTION], GetDefStr(sm_szLoadKeys[OBC_SUBSECTION]));
			return true;
		}
		case OBC_ARMOR:
		{
			INT64 piVal[2];
			size_t iQty = Str_ParseCmds(s.GetArgStr(), piVal, COUNTOF(piVal));
			m_defenseBase = static_cast<WORD>(piVal[0]);
			if ( iQty > 1 )
				m_defenseRange = static_cast<WORD>(piVal[1]) - m_defenseBase;
			else
				m_defenseRange = 0;
			return true;
		}
		case OBC_BASEID:
			return false;
		case OBC_CAN:
			m_Can = s.GetArgVal();	//| (m_Can & (CAN_C_INDOORS|CAN_C_EQUIP|CAN_C_USEHANDS|CAN_C_NONHUMANOID));	//fixed #2326?
			return true;
		case OBC_DAM:
		{
			INT64 piVal[2];
			size_t iQty = Str_ParseCmds(s.GetArgStr(), piVal, COUNTOF(piVal));
			m_attackBase = static_cast<WORD>(piVal[0]);
			if ( iQty > 1 )
				m_attackRange = static_cast<WORD>(piVal[1]) - m_attackBase;
			else
				m_attackRange = 0;
			return true;
		}
		case OBC_DAMCOLD:
			m_DamCold = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_DAMENERGY:
			m_DamEnergy = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_DAMFIRE:
			m_DamFire = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_DAMPHYSICAL:
			m_DamPhysical = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_DAMPOISON:
			m_DamPoison = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_DEFNAME:
		case OBC_DEFNAME2:
			return SetResourceName(s.GetArgStr());
		case OBC_ENHANCEPOTIONS:
			m_EnhancePotions = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_FASTERCASTING:
			m_FasterCasting = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_FASTERCASTRECOVERY:
			m_FasterCastRecovery = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_HEIGHT:
			m_Height = static_cast<height_t>(s.GetArgVal());
			return true;
		case OBC_HITLEECHLIFE:
			m_HitLifeLeech = static_cast<int>(s.GetArgVal());
			break;
		case OBC_HITLEECHMANA:
			m_HitManaLeech = static_cast<int>(s.GetArgVal());
			break;
		case OBC_HITLEECHSTAM:
			m_HitStaminaLeech = static_cast<int>(s.GetArgVal());
			break;
		case OBC_HITMANADRAIN:
			m_HitManaDrain = static_cast<int>(s.GetArgVal());
			break;
		case OBC_INCREASEDAM:
			m_DamIncrease = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_INCREASEDEFCHANCE:
			m_DefChanceIncrease = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_INCREASEDEFCHANCEMAX:
			m_DefChanceIncreaseMax = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_INCREASEHITCHANCE:
			m_HitChanceIncrease = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_INCREASESPELLDAM:
			m_SpellDamIncrease = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_INCREASESWINGSPEED:
			m_SwingSpeedIncrease = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_INSTANCES:
			return false;
		case OBC_LOWERMANACOST:
			m_LowerManaCost = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_LOWERREAGENTCOST:
			m_LowerReagentCost = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_LUCK:
			m_Luck = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_NAME:
			SetTypeName(s.GetArgStr());
			return true;
		case OBC_NIGHTSIGHT:
			m_NightSight = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_REFLECTPHYSICALDAM:
			m_ReflectPhysicalDamage = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RANGE:
		{
			INT64 piVal[2];
			size_t iQty = Str_ParseCmds(s.GetArgStr(), piVal, COUNTOF(piVal));
			if ( iQty > 1 )
			{
				INT64 iRange = ((piVal[0] & 0xFF) << 8) & 0xFF00;
				iRange |= (piVal[1] & 0xFF);
				SetDefNum(s.GetKey(), iRange, false);
				//m_range = ((piVal[0] & 0xFF) << 8) & 0xFF00;
				//m_range |= (piVal[1] & 0xFF);
			}
			else
			{
				SetDefNum(s.GetKey(), piVal[0], false);
				//m_range = static_cast<WORD>(piVal[0]);
			}
			return true;
		}
		case OBC_RESCOLD:
			m_ResCold = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESCOLDMAX:
			m_ResColdMax = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESDISPDNHUE:
			SetResDispDnHue(static_cast<HUE_TYPE>(s.GetArgVal()));
			return true;
		case OBC_RESENERGY:
			m_ResEnergy = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESENERGYMAX:
			m_ResEnergyMax = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESFIRE:
			m_ResFire = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESFIREMAX:
			m_ResFireMax = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESLEVEL:
			return SetResLevel(minimum(maximum(s.GetArgVal(), RDS_NONE), RDS_QTY - 1));
		case OBC_RESOURCES:
			m_BaseResources.Load(s.GetArgStr());
			return true;
		case OBC_RESPHYSICAL:
			m_ResPhysical = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESPHYSICALMAX:
			m_ResPhysicalMax = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESPOISON:
			m_ResPoison = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_RESPOISONMAX:
			m_ResPoisonMax = static_cast<int>(s.GetArgVal());
			return true;
		case OBC_TEVENTS:
			return m_TEvents.r_LoadVal(s, RES_EVENTS);
	}
	return CScriptObj::r_LoadVal(s);
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPT;
	EXC_DEBUG_END;
	return false;
}
Exemple #29
0
bool CClient::r_Verb( CScript & s, CTextConsole * pSrc ) // Execute command from script
{
	ADDTOCALLSTACK("CClient::r_Verb");
	EXC_TRY("Verb");
	// NOTE: This can be called directly from a RES_WEBPAGE script.
	//  So do not assume we are a game client !
	// NOTE: Mostly called from CChar::r_Verb
	// NOTE: Little security here so watch out for dangerous scripts !

	ASSERT(pSrc);
	LPCTSTR pszKey = s.GetKey();

	// Old ver
	if ( s.IsKeyHead( "SET", 3 ) && ( g_Cfg.m_Functions.ContainsKey( pszKey ) == false ) )
	{
		PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel( "SET" );
		if ( ilevel > GetPrivLevel() )
			return( false );

		ASSERT( m_pChar );
		addTargetVerb( pszKey+3, s.GetArgRaw());
		return( true );
	}

	if ( toupper( pszKey[0] ) == 'X' && ( g_Cfg.m_Functions.ContainsKey( pszKey ) == false ) )
	{
		PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel( "SET" );
		if ( ilevel > GetPrivLevel() )
			return( false );

		// Target this command verb on some other object.
		ASSERT( m_pChar );
		addTargetVerb( pszKey+1, s.GetArgRaw());
		return( true );
	}

	int index = FindTableSorted( s.GetKey(), sm_szVerbKeys, COUNTOF(sm_szVerbKeys)-1 );
	switch (index)
	{
		case CV_ADD:
			if ( s.HasArgs())
			{
				// FindItemName ???
				TCHAR * pszArgs = s.GetArgStr();
				if ( !IsValidGameObjDef( static_cast<LPCTSTR>(pszArgs) ) )
				{
					g_Log.EventWarn("Invalid ADD argument '%s'\n", pszArgs);
					SysMessageDefault( DEFMSG_CMD_INVALID );
					return true;
				}

				RESOURCE_ID rid = g_Cfg.ResourceGetID( RES_QTY, const_cast<LPCTSTR &>(reinterpret_cast<LPTSTR &>(pszArgs)));
				if (( rid.GetResType() == RES_CHARDEF ) || ( rid.GetResType() == RES_SPAWN ))
				{
					m_Targ_PrvUID.InitUID();
					return Cmd_CreateChar(static_cast<CREID_TYPE>(rid.GetResIndex()), SPELL_Summon, false );
				}

				ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex());
				return Cmd_CreateItem( id );
			}
			else
			{
				if ( IsValidDef( "d_add" ) )
					Dialog_Setup( CLIMODE_DIALOG, g_Cfg.ResourceGetIDType(RES_DIALOG, "d_add"), 0, this->GetChar() );
				else
					Menu_Setup( g_Cfg.ResourceGetIDType( RES_MENU, "MENU_ADDITEM"));	
			}
			break;
		case CV_ADDBUFF:
			{
				TCHAR * ppArgs[11];
				Str_ParseCmds( s.GetArgStr(), ppArgs, COUNTOF(ppArgs));

				int iArgs[4];
				for ( int idx = 0; idx < 4; ++idx )
				{
					if ( !IsStrNumeric(ppArgs[idx]))
					{
						DEBUG_ERR(("Invalid AddBuff argument number %u\n", idx+1));
						return true;
					}
					iArgs[idx] = Exp_GetVal( ppArgs[idx] );
				}
				if (iArgs[0] < BI_START || iArgs[0] > BI_QTY/* || iArgs[0] == 0x3EB || iArgs[0] == 0x3EC*/) {	// 0x3eb and 0x3ec among some others does not exists now, which doesn't mean they won't fill them and, since nothing happens when wrong id is sent, we can let them be sent.
					DEBUG_ERR(("Invalid AddBuff icon ID\n"));
					break;
				}

				LPCTSTR Args[7];
				size_t ArgsCount = 0;
				for ( int i = 0; i < 7; ++i )
				{
					Args[i] = ppArgs[i + 4];
					if ( Args[i] != NULL )
						ArgsCount++;
				}

				addBuff(static_cast<BUFF_ICONS>(iArgs[0]), iArgs[1], iArgs[2], static_cast<WORD>(iArgs[3]), Args, ArgsCount);
			}
			break;
		case CV_REMOVEBUFF:
			{
				BUFF_ICONS IconId = static_cast<BUFF_ICONS>(s.GetArgVal());
				if (IconId < BI_START || IconId > BI_QTY/* || IconId == 0x3EB || IconId == 0x3EC*/) {
					DEBUG_ERR(("Invalid RemoveBuff icon ID\n"));
					break;
				}
				removeBuff(IconId);
			}
			break;
		case CV_ADDCLILOC:
			// Add cliloc in @ClientTooltip trigger
			{
				TCHAR * ppLocArgs[256];
				size_t qty = Str_ParseCmds(s.GetArgRaw(), ppLocArgs, COUNTOF(ppLocArgs), ",");
				DWORD clilocid = Exp_GetVal(ppLocArgs[0]);

				CGString LocArgs;
				for ( size_t y = 1 ; y < qty; y++ )
				{
					if ( LocArgs.GetLength() )
						LocArgs += "\t";
					LocArgs += ( !strcmp(ppLocArgs[y], "NULL") ? " " : ppLocArgs[y] );
				}

				if ( g_Cfg.m_wDebugFlags & DEBUGF_SCRIPTS )
					g_Log.EventDebug("SCRIPT: addcliloc(%lu,'%s')\n", clilocid, static_cast<LPCTSTR>(LocArgs));
				this->m_TooltipData.Add(new CClientTooltip(clilocid, LocArgs));
			}
			break;
		case CV_ADDCONTEXTENTRY:
			{
				TCHAR * ppLocArgs[20];
				if ( Str_ParseCmds(s.GetArgRaw(), ppLocArgs, COUNTOF(ppLocArgs), ",") > 4 )
				{
					DEBUG_ERR(("Bad AddContextEntry usage: Function takes maximum of 4 arguments!\n"));
					return true;
				}

				if (m_pPopupPacket == NULL)
				{
					DEBUG_ERR(("Bad AddContextEntry usage: Not used under a @ContextMenuRequest/@itemContextMenuRequest trigger!\n"));
					return true;
				}

				for ( int i = 0; i < 4; i++ )
				{
					if ( i > 1 && IsStrEmpty(ppLocArgs[i]) )
						continue;

					if ( !IsStrNumeric(ppLocArgs[i]) )
					{
						DEBUG_ERR(("Bad AddContextEntry usage: Argument %d must be a number!\n", i+1));
						return true;
					}
				}

				int entrytag = Exp_GetVal(ppLocArgs[0]);
				if ( entrytag < 100 )
				{
					DEBUG_ERR(("Bad AddContextEntry usage: TextEntry < 100 is reserved for server usage!\n"));
					return true;
				}
				m_pPopupPacket->addOption(static_cast<WORD>(entrytag), static_cast<DWORD>(Exp_GetVal(ppLocArgs[1])), static_cast<WORD>(Exp_GetVal(ppLocArgs[2])), static_cast<WORD>(Exp_GetVal(ppLocArgs[3])));
			}
			break;
		case CV_ARROWQUEST:
			{
				INT64 piVal[3];
				Str_ParseCmds( s.GetArgRaw(), piVal, COUNTOF(piVal));
				addArrowQuest( static_cast<int>(piVal[0]), static_cast<int>(piVal[1]), static_cast<int>(piVal[2]) );
#ifdef _ALPHASPHERE
				// todo: should use a proper container for these, since the arrows are lost
				// when the client logs out, and also newer clients support multiple
				// arrows
				if ( piVal[0] && piVal[1] && m_pChar )
				{
					m_pChar->SetKeyNum("ARROWQUEST_X", piVal[0]);
					m_pChar->SetKeyNum("ARROWQUEST_Y", piVal[1]);
				} else {
					m_pChar->DeleteKey("ARROWQUEST_X");
					m_pChar->DeleteKey("ARROWQUEST_Y");
				}
#endif
			}
			break;
		case CV_BADSPAWN:
			{
				//	Loop the world searching for bad spawns
				bool fFound = false;
				for ( int m = 0; m < 256 && !fFound; m++ )
				{
					if ( !g_MapList.m_maps[m] ) continue;

					for ( int d = 0; d < g_MapList.GetSectorQty(m) && !fFound; d++ )
					{
						CSector	*pSector = g_World.GetSector(m, d);
						if ( !pSector ) continue;

						CItem	*pNext;
						CItem	*pItem = STATIC_CAST <CItem*>(pSector->m_Items_Inert.GetHead());
						for ( ; pItem != NULL && !fFound; pItem = pNext )
						{
							pNext = pItem->GetNext();

							if ( pItem->IsType(IT_SPAWN_ITEM) || pItem->IsType(IT_SPAWN_CHAR) )
							{
								CItemSpawn *pSpawn = static_cast<CItemSpawn*>(pItem);
								CResourceDef	*pDef = pSpawn->FixDef();
								if ( !pDef )
								{
									RESOURCE_ID_BASE	rid = ( pItem->IsType(IT_SPAWN_ITEM) ? pItem->m_itSpawnItem.m_ItemID : pItem->m_itSpawnChar.m_CharID);

									CPointMap	pt = pItem->GetTopPoint();
									m_pChar->Spell_Teleport(pt, true, false);
									m_pChar->m_Act_Targ = pItem->GetUID();
									SysMessagef("Bad spawn (0%lx, id=%s). Set as ACT", (DWORD)pItem->GetUID(), g_Cfg.ResourceGetName(rid));
									fFound = true;
								}
							}
						}
					}
				}
				if ( ! fFound )
					SysMessage(g_Cfg.GetDefaultMsg( DEFMSG_NO_BAD_SPAWNS ));
			}
			break;
		case CV_BANKSELF: // open my own bank
			addBankOpen( m_pChar, static_cast<LAYER_TYPE>(s.GetArgVal()));
			break;
		case CV_CAST:
			{
				SPELL_TYPE spell = static_cast<SPELL_TYPE>(g_Cfg.ResourceGetIndexType(RES_SPELL, s.GetArgStr()));
				const CSpellDef * pSpellDef = g_Cfg.GetSpellDef(spell);
				if (pSpellDef == NULL)
					return true;

				CObjBase * pObjSrc = dynamic_cast<CObjBase *>(pSrc);

				if ( IsSetMagicFlags( MAGICF_PRECAST ) && !pSpellDef->IsSpellType( SPELLFLAG_NOPRECAST ) )
				{
					int skill;
					if (!pSpellDef->GetPrimarySkill(&skill, NULL))
						return true;

					m_tmSkillMagery.m_Spell = spell;	// m_atMagery.m_Spell
					m_pChar->m_atMagery.m_Spell = spell;
					if (pObjSrc != NULL)
					{
						m_Targ_UID = pObjSrc->GetUID();	// default target.
						m_Targ_PrvUID = pObjSrc->GetUID();
					}
					else
					{
						m_Targ_UID.ClearUID();
						m_Targ_PrvUID.ClearUID();
					}
					m_pChar->Skill_Start(static_cast<SKILL_TYPE>(skill));
					break;
				}
				else
					Cmd_Skill_Magery(spell, pObjSrc);
			}
			break;

		case CV_CHARLIST:
			{
				// usually just a gm command
				new PacketChangeCharacter(this);

				CharDisconnect();	// since there is no undoing this in the client.
				SetTargMode( CLIMODE_SETUP_CHARLIST );
			}
			break;

		case CV_CTAGLIST:
			if ( ! strcmpi( s.GetArgStr(), "log" ))
				pSrc = &g_Serv;
			m_TagDefs.DumpKeys(pSrc, "CTAG.");
			break;

		case CV_CLEARCTAGS:
			{
				if ( s.HasArgs() )
				{
					LPCTSTR pszArgs = s.GetArgStr();
					SKIP_SEPARATORS(pszArgs);
					m_TagDefs.ClearKeys(pszArgs);
				}
				else
				{
					m_TagDefs.ClearKeys();
				}
			} break;

		case CV_CLOSEPAPERDOLL:
			{
				CChar *pChar = m_pChar;
				if ( s.HasArgs() )
				{
					CGrayUID uid = s.GetArgVal();
					pChar = uid.CharFind();
				}
				if ( pChar )
					closeUIWindow(pChar, 0x01);
			}
			break;

		case CV_CLOSEPROFILE:
			{
				CChar *pChar = m_pChar;
				if ( s.HasArgs() )
				{
					CGrayUID uid = s.GetArgVal();
					pChar = uid.CharFind();
				}
				if ( pChar )
					closeUIWindow(pChar, 0x08);
			}
			break;

		case CV_CLOSESTATUS:
			{
				CChar *pChar = m_pChar;
				if ( s.HasArgs() )
				{
					CGrayUID uid = s.GetArgVal();
					pChar = uid.CharFind();
				}
				if ( pChar )
					closeUIWindow(pChar, 0x02);
			}
			break;

		case CV_DYE:
			if ( s.HasArgs() )
			{
				CGrayUID uid(s.GetArgVal());
				CObjBase *pObj = uid.ObjFind();
				if ( pObj )
					addDyeOption(pObj);
			}
			break;

		case CV_EVERBTARG:
			m_Prompt_Text = s.GetArgStr();
			addPromptConsole( CLIMODE_PROMPT_TARG_VERB, m_Targ_Text.IsEmpty() ? "Enter the verb" : "Enter the text",  m_Targ_UID );
			break;

		case CV_EXTRACT:
			// sort of like EXPORT but for statics.
			// Opposite of the "UNEXTRACT" command

			if ( ! s.HasArgs())
			{
				SysMessage( g_Cfg.GetDefaultMsg( DEFMSG_EXTRACT_USAGE ) );
			}
			else
			{
				TCHAR * ppArgs[2];
				Str_ParseCmds( s.GetArgStr(), ppArgs, COUNTOF( ppArgs ));

				m_Targ_Text = ppArgs[0]; // Point at the options, if any
				m_tmTile.m_ptFirst.InitPoint(); // Clear this first
				m_tmTile.m_Code = CV_EXTRACT;	// set extract code.
				m_tmTile.m_id = Exp_GetVal(ppArgs[1]);	// extract id.
				addTarget( CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_EXTRACT_AREA ), true );
			}
			break;

		case CV_UNEXTRACT:
			// Create item from script.
			// Opposite of the "EXTRACT" command
			if ( ! s.HasArgs())
			{
				SysMessage( g_Cfg.GetDefaultMsg( DEFMSG_UNEXTRACT_USAGE ) );
			}
			else
			{
				TCHAR * ppArgs[2];
				Str_ParseCmds( s.GetArgStr(), ppArgs, COUNTOF( ppArgs ));

				m_Targ_Text = ppArgs[0]; // Point at the options, if any
				m_tmTile.m_ptFirst.InitPoint(); // Clear this first
				m_tmTile.m_Code = CV_UNEXTRACT;	// set extract code.
				m_tmTile.m_id = Exp_GetVal(ppArgs[1]);	// extract id.

				addTarget( CLIMODE_TARG_UNEXTRACT, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_MULTI_POS ), true );
			}
			break;

		case CV_GMPAGE:
			m_Targ_Text = s.GetArgStr();
			if ( !m_Targ_Text.IsEmpty() && !strnicmp( m_Targ_Text, "ADD ", 4 ) )
			{
				Cmd_GM_Page( m_Targ_Text + 4 );
				break;
			}
			addPromptConsole( CLIMODE_PROMPT_GM_PAGE_TEXT, g_Cfg.GetDefaultMsg( DEFMSG_GMPAGE_PROMPT ) );
			break;
		case CV_GOTARG: // go to my (preselected) target.
			{
				ASSERT(m_pChar);
				CObjBase * pObj = m_Targ_UID.ObjFind();
				if ( pObj != NULL )
				{
					CPointMap po = pObj->GetTopLevelObj()->GetTopPoint();
					CPointMap pnt = po;
					pnt.MoveN( DIR_W, 3 );
					DWORD wBlockFlags = m_pChar->GetMoveBlockFlags();
					pnt.m_z = g_World.GetHeightPoint2( pnt, wBlockFlags );	// ??? Get Area
					m_pChar->m_dirFace = pnt.GetDir( po, m_pChar->m_dirFace ); // Face the player
					m_pChar->Spell_Teleport( pnt, true, false );
				}
			}
			break;
		case CV_INFO:
			// We could also get ground tile info.
			addTarget( CLIMODE_TARG_OBJ_INFO, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_ITEM_INFO ), true, false );
			break;
		case CV_INFORMATION:
			SysMessage( g_Serv.GetStatusString( 0x22 ));
			SysMessage( g_Serv.GetStatusString( 0x24 ));
			break;
		case CV_LAST:
			// Fake Previous target.
			if ( GetTargMode() >= CLIMODE_MOUSE_TYPE )
			{
				ASSERT(m_pChar);
				CObjBase * pObj = m_pChar->m_Act_Targ.ObjFind();
				if ( pObj != NULL )
				{
					Event_Target(GetTargMode(), pObj->GetUID(), pObj->GetUnkPoint());
					addTargetCancel();
				}
				break;
			}
			return( false );
		case CV_LINK:	// link doors
			m_Targ_UID.InitUID();
			addTarget( CLIMODE_TARG_LINK, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_LINK_ITEM ) );
			break;

		case CV_MENU:
			Menu_Setup( g_Cfg.ResourceGetIDType( RES_MENU, s.GetArgStr()));
			break;
		case CV_MIDILIST:
			{
				INT64 piMidi[64];
				size_t iQty = Str_ParseCmds( s.GetArgStr(), piMidi, COUNTOF(piMidi));
				if ( iQty > 0 )
				{
					addMusic( static_cast<MIDI_TYPE>(piMidi[ Calc_GetRandVal( iQty ) ]) );
				}
			}
			break;
		case CV_NUDGE:
			if ( ! s.HasArgs())
			{
				SysMessage( "Usage: NUDGE dx dy dz" );
			}
			else
			{
				m_Targ_Text = s.GetArgRaw();
				m_tmTile.m_ptFirst.InitPoint(); // Clear this first
				m_tmTile.m_Code = CV_NUDGE;
				addTarget( CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_NUDGE_AREA ), true );
			}
			break;

		case CV_NUKE:
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint(); // Clear this first
			m_tmTile.m_Code = CV_NUKE;	// set nuke code.
			addTarget( CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_NUKE_AREA ), true );
			break;
		case CV_NUKECHAR:
			m_Targ_Text = s.GetArgRaw();
			m_tmTile.m_ptFirst.InitPoint(); // Clear this first
			m_tmTile.m_Code = CV_NUKECHAR;	// set nuke code.
			addTarget( CLIMODE_TARG_TILE, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_NUKE_CHAR_AREA ), true );
			break;

		case CV_OPENPAPERDOLL:
		{
			CChar *pChar = m_pChar;
			if ( s.HasArgs() )
			{
				CGrayUID uid = s.GetArgVal();
				pChar = uid.CharFind();
			}
			if ( pChar )
				addCharPaperdoll(pChar);
		}
		break;

		case CV_PAGE:
			Cmd_GM_PageCmd( s.GetArgStr());
			break;
		case CV_REPAIR:
			addTarget( CLIMODE_TARG_REPAIR, g_Cfg.GetDefaultMsg( DEFMSG_SELECT_ITEM_REPAIR ) );
			break;
		case CV_FLUSH:
#ifndef _MTNETWORK
			g_NetworkOut.flush(this);
#else
			g_NetworkManager.flush(GetNetState());
#endif
			break;
		case CV_RESEND:
			addReSync();
			break;
		case CV_SAVE:
			g_World.Save(s.GetArgVal() != 0);
			break;
		case CV_SCROLL:
			// put a scroll up.
			addScrollResource( s.GetArgStr(), SCROLL_TYPE_UPDATES );
			break;
		case CV_SENDPACKET:
			SendPacket( s.GetArgStr() );
			break;
		case CV_SELF:
			// Fake self target.
			if ( GetTargMode() >= CLIMODE_MOUSE_TYPE )
			{
				ASSERT(m_pChar);
				Event_Target(GetTargMode(), m_pChar->GetUID(), m_pChar->GetTopPoint());
				addTargetCancel();
				break;
			}
			return( false );
		case CV_SHOWSKILLS:
			addSkillWindow(static_cast<SKILL_TYPE>(g_Cfg.m_iMaxSkill)); // Reload the real skills
			break;
		case CV_SKILLMENU:				// Just put up another menu.
			Cmd_Skill_Menu( g_Cfg.ResourceGetIDType( RES_SKILLMENU, s.GetArgStr()));
			break;
		case CV_SKILLSELECT:
			Event_Skill_Use( g_Cfg.FindSkillKey( s.GetArgStr() ) );
			break;
		case CV_SUMMON:	// from the spell skill script.
			// m_Targ_PrvUID should already be set.
			return Cmd_CreateChar(static_cast<CREID_TYPE>(g_Cfg.ResourceGetIndexType( RES_CHARDEF, s.GetArgStr())), SPELL_Summon, true );
		case CV_SMSG:
		case CV_SYSMESSAGE:
			SysMessage( s.GetArgStr() );
			break;
		case CV_SYSMESSAGEF: //There is still an issue with numbers not resolving properly when %i,%d,or other numeric format code is in use
			{
				TCHAR * pszArgs[4];
				size_t iArgQty = Str_ParseCmds( s.GetArgRaw(), pszArgs, COUNTOF(pszArgs) );
				if ( iArgQty < 2 )
				{
					g_Log.EventError("SysMessagef with less than 1 args for the given text\n");
					return false;
				}
				if ( iArgQty > 4 )
				{
					g_Log.EventError("Too many arguments given to SysMessagef (max = text + 3\n");
					return false;
				}
				//strip quotes if any
				if ( *pszArgs[0] == '"' )
					pszArgs[0]++;
				for (TCHAR * pEnd = pszArgs[0] + strlen( pszArgs[0] ) - 1; pEnd >= pszArgs[0]; pEnd-- )
				{
					if ( *pEnd == '"' )
					{
						*pEnd = '\0';
						break;
					}
				}
				SysMessagef( pszArgs[0], pszArgs[1], pszArgs[2] ? pszArgs[2] : 0, pszArgs[3] ? pszArgs[3] : 0);
			}break;
		case CV_SMSGU:
		case CV_SYSMESSAGEUA:
			{
				TCHAR * pszArgs[5];
				size_t iArgQty = Str_ParseCmds( s.GetArgRaw(), pszArgs, COUNTOF(pszArgs) );
				if ( iArgQty > 4 )
				{
					// Font and mode are actually ignored here, but they never made a difference
					// anyway.. I'd like to keep the syntax similar to SAYUA
			 		NCHAR szBuffer[ MAX_TALK_BUFFER ];
					CvtSystemToNUNICODE( szBuffer, COUNTOF(szBuffer), pszArgs[4], -1 );

					addBarkUNICODE( szBuffer, NULL, static_cast<HUE_TYPE>(Exp_GetVal(pszArgs[0])), TALKMODE_SYSTEM, FONT_NORMAL, pszArgs[3] );
				}
			}
			break;
		case CV_SMSGL:
		case CV_SYSMESSAGELOC:
			{
				TCHAR * ppArgs[256];
				size_t iArgQty = Str_ParseCmds( s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), "," );
				if ( iArgQty > 1 )
				{
					int hue = -1;
					if ( ppArgs[0] )
						hue = Exp_GetVal( ppArgs[0] );
					int iClilocId = Exp_GetVal( ppArgs[1] );

					if ( hue == -1 )	hue = HUE_TEXT_DEF;

					CGString CArgs;
					for ( size_t i = 2; i < iArgQty; i++ )
					{
						if ( CArgs.GetLength() )
							CArgs += "\t";
						CArgs += ( !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i] );
					}

					addBarkLocalized(iClilocId, NULL, static_cast<HUE_TYPE>(hue), TALKMODE_SYSTEM, FONT_NORMAL, CArgs.GetPtr());
				}
			}
			break;
		case CV_SMSGLEX:
		case CV_SYSMESSAGELOCEX:
			{
				TCHAR * ppArgs[256];
				size_t iArgQty = Str_ParseCmds( s.GetArgRaw(), ppArgs, COUNTOF(ppArgs), "," );
				if ( iArgQty > 2 )
				{
					int hue = -1;
					int affix = 0;
					if ( ppArgs[0] )
						hue = Exp_GetVal( ppArgs[0] );
					int iClilocId = Exp_GetVal( ppArgs[1] );
					if ( ppArgs[2] )
						affix = Exp_GetVal( ppArgs[2] );

					if ( hue == -1 )	hue = HUE_TEXT_DEF;

					CGString CArgs;
					for ( size_t i = 4; i < iArgQty; i++ )
					{
						if ( CArgs.GetLength() )
							CArgs += "\t";
						CArgs += ( !strcmp(ppArgs[i], "NULL") ? " " : ppArgs[i] );
					}

					addBarkLocalizedEx( iClilocId, NULL, static_cast<HUE_TYPE>(hue), TALKMODE_SYSTEM, FONT_NORMAL, static_cast<AFFIX_TYPE>(affix), ppArgs[3], CArgs.GetPtr() );
				}
			}
			break;
		case CV_TELE:
			Cmd_Skill_Magery(SPELL_Teleport, dynamic_cast<CObjBase *>(pSrc));
			break;
		case CV_TILE:
			if ( ! s.HasArgs())
			{
				SysMessage( "Usage: TILE z-height item1 item2 itemX" );
			}
			else
			{
				m_Targ_Text = s.GetArgStr(); // Point at the options
				m_tmTile.m_ptFirst.InitPoint(); // Clear this first
				m_tmTile.m_Code = CV_TILE;
				addTarget( CLIMODE_TARG_TILE, "Pick 1st corner:", true );
			}
			break;
		case CV_VERSION:	// "SHOW VERSION"
			SysMessage(g_szServerDescription);
			break;
		case CV_WEBLINK:
			addWebLaunch( s.GetArgStr());
			break;
		default:
			if ( r_LoadVal( s ))
			{
				CGString sVal;
				if ( r_WriteVal( s.GetKey(), sVal, pSrc ))
				{
					// if ( !s.IsKeyHead( "CTAG.", 5 ) && !s.IsKeyHead( "CTAG0.", 6 ) ) // We don't want output related to ctag
					//	SysMessagef( "%s = %s", (LPCTSTR) s.GetKey(), (LPCTSTR) sVal );	// feedback on what we just did.

					return( true );
				}
			}
			return( CScriptObj::r_Verb( s, pSrc ));	// used in the case of web pages to access server level things..
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPTSRC;
	EXC_DEBUG_END;
	return false;
}
Exemple #30
0
llong CExpression::GetSingle( lpctstr & pszArgs )
{
	ADDTOCALLSTACK("CExpression::GetSingle");
	// Parse just a single expression without any operators or ranges.
	ASSERT(pszArgs);
	GETNONWHITESPACE( pszArgs );

	lpctstr orig = pszArgs;
	if (pszArgs[0]=='.')
		++pszArgs;

	if ( pszArgs[0] == '0' )	// leading '0' = hex value.
	{
		// A hex value.
		if ( pszArgs[1] == '.' )	// leading 0. means it really is decimal.
		{
			pszArgs += 2;
			goto try_dec;
		}

		lpctstr pStart = pszArgs;
		ullong val = 0;
		while (true)
		{
			tchar ch = *pszArgs;
			if ( IsDigit(ch) )
				ch -= '0';
			else
			{
				ch = static_cast<tchar>(tolower(ch));
				if ( ch > 'f' || ch < 'a' )
				{
					if ( ch == '.' && pStart[0] != '0' )	// ok i'm confused. it must be decimal.
					{
						pszArgs = pStart;
						goto try_dec;
					}
					break;
				}
				ch -= 'a' - 10;
			}
			val *= 0x10;
			val += ch;
			++pszArgs;
		}
		return (llong)val;
	}
	else if ( pszArgs[0] == '.' || IsDigit(pszArgs[0]) )
	{
		// A decminal number
try_dec:
		llong iVal = 0;
		for ( ; ; ++pszArgs )
		{
			if ( *pszArgs == '.' )
				continue;	// just skip this.
			if ( ! IsDigit(*pszArgs) )
				break;
			iVal *= 10;
			iVal += *pszArgs - '0';
		}
		return iVal;
	}
	else if ( ! _ISCSYMF(pszArgs[0]) )
	{
	#pragma region maths
		// some sort of math op ?

		switch ( pszArgs[0] )
		{
		case '{':
			++pszArgs;
			return GetRangeNumber( pszArgs );
		case '[':
		case '(': // Parse out a sub expression.
			++pszArgs;
			return GetVal( pszArgs );
		case '+':
			++pszArgs;
			break;
		case '-':
			++pszArgs;
			return -GetSingle( pszArgs );
		case '~':	// Bitwise not.
			++pszArgs;
			return ~GetSingle( pszArgs );
		case '!':	// boolean not.
			++pszArgs;
			if ( pszArgs[0] == '=' )  // odd condition such as (!=x) which is always true of course.
			{
				++pszArgs;		// so just skip it. and compare it to 0
				return GetSingle( pszArgs );
			}
			return !GetSingle( pszArgs );
		case ';':	// seperate field.
		case ',':	// seperate field.
		case '\0':
			return 0;
		}
#pragma endregion maths
	}
	else
	#pragma region intrinsics
	{
		// Symbol or intrinsinc function ?

		INTRINSIC_TYPE iIntrinsic = (INTRINSIC_TYPE) FindTableHeadSorted( pszArgs, sm_IntrinsicFunctions, CountOf(sm_IntrinsicFunctions)-1 );
		if ( iIntrinsic >= 0 )
		{
			size_t iLen = strlen(sm_IntrinsicFunctions[iIntrinsic]);
			if ( pszArgs[iLen] == '(' )
			{
				pszArgs += (iLen + 1);
				tchar * pszArgsNext;
				Str_Parse( const_cast<tchar*>(pszArgs), &(pszArgsNext), ")" );

				tchar * ppCmd[5];
				llong iResult;
				size_t iCount = 0;

				switch ( iIntrinsic )
				{
					case INTRINSIC_ID:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = RES_GET_INDEX( GetVal(pszArgs) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

                    case INTRINSIC_MAX:
                    {
                        iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
                        if ( iCount < 2 )
                            iResult = 0;
                        else
                        {
                            const int64 iVal1 = GetVal(ppCmd[0]), iVal2 = GetVal(ppCmd[1]);
                            iResult = maximum(iVal1, iVal2);
                        }
                    } break;

                    case INTRINSIC_MIN:
                    {
                        iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
                        if ( iCount < 2 )
                            iResult = 0;
                        else
                        {
                            const int64 iVal1 = GetVal(ppCmd[0]), iVal2 = GetVal(ppCmd[1]);
                            iResult = minimum(iVal1, iVal2);
                        }
                    } break;

					case INTRINSIC_LOGARITHM:
					{
						iCount = 0;
						iResult = 0;

						if ( pszArgs && *pszArgs )
						{
							llong iArgument = GetVal(pszArgs);
							if ( iArgument <= 0 )
							{
								DEBUG_ERR(( "Exp_GetVal: (x)Log(%" PRId64 ") is %s\n", iArgument, (!iArgument) ? "infinite" : "undefined" ));
							}
							else
							{
								iCount = 1;

								if ( strchr(pszArgs, ',') )
								{
									++iCount;
									SKIP_ARGSEP(pszArgs);
									if ( !strcmpi(pszArgs, "e") )
									{
										iResult = (llong)log( (double)iArgument );
									}
									else if ( !strcmpi(pszArgs, "pi") )
									{
										iResult = (llong)(log( (double)iArgument ) / log( M_PI ) );
									}
									else
									{
										llong iBase = GetVal(pszArgs);
										if ( iBase <= 0 )
										{
											DEBUG_ERR(( "Exp_GetVal: (%" PRId64 ")Log(%" PRId64 ") is %s\n", iBase, iArgument, (!iBase ? "infinite" : "undefined") ));
											iCount = 0;
										}
										else
											iResult = (llong)(log( (double)iArgument ) / log( (double)iBase ));
									}
								}
								else
									iResult = (llong)log10( (double)iArgument );
							}
						}

					} break;

					case INTRINSIC_NAPIERPOW:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)exp( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_SQRT:
					{
						iCount = 0;
						iResult = 0;

						if ( pszArgs && *pszArgs )
						{
							llong iTosquare = GetVal(pszArgs);

							if (iTosquare >= 0)
							{
								++iCount;
								iResult = (llong)sqrt( (double)iTosquare );
							}
							else
								DEBUG_ERR(( "Exp_GetVal: Sqrt of negative number (%" PRId64 ") is impossible\n", iTosquare ));
						}

					} break;

					case INTRINSIC_SIN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)sin( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCSIN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)asin( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_COS:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)cos( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCCOS:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)acos( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_TAN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)tan( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_ARCTAN:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = (llong)atan( (double)GetVal( pszArgs ) );
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}

					} break;

					case INTRINSIC_StrIndexOf:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 3, "," );
						if ( iCount < 2 )
							iResult = -1;
						else
							iResult = Str_IndexOf( ppCmd[0] , ppCmd[1] , (iCount==3)?(int)GetVal(ppCmd[2]):0 );
					} break;

					case INTRINSIC_STRMATCH:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
							iResult = (Str_Match( ppCmd[0], ppCmd[1] ) == MATCH_VALID ) ? 1 : 0;
					} break;

					case INTRINSIC_STRREGEX:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
						{
							tchar * tLastError = Str_GetTemp();
							iResult = Str_RegExMatch( ppCmd[0], ppCmd[1], tLastError );
							if ( iResult == -1 )
							{
								DEBUG_ERR(( "STRREGEX bad function usage. Error: %s\n", tLastError ));
							}
						}
					} break;

					case INTRINSIC_RANDBELL:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 0;
						else
							iResult = Calc_GetBellCurve( (int)GetVal( ppCmd[0] ), (int)GetVal( ppCmd[1] ) );
					} break;

					case INTRINSIC_STRASCII:
					{
						if ( pszArgs && *pszArgs )
						{
							iCount = 1;
							iResult = pszArgs[0];
						}
						else
						{
							iCount = 0;
							iResult = 0;
						}
					} break;

					case INTRINSIC_RAND:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount <= 0 )
							iResult = 0;
						else
						{
							int64 val1 = GetVal( ppCmd[0] );
							if ( iCount == 2 )
							{
								int64 val2 = GetVal( ppCmd[1] );
								iResult = Calc_GetRandLLVal2( val1, val2 );
							}
							else
								iResult = Calc_GetRandLLVal(val1);
						}
					} break;

					case INTRINSIC_STRCMP:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 1;
						else
							iResult = strcmp(ppCmd[0], ppCmd[1]);
					} break;

					case INTRINSIC_STRCMPI:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 2, "," );
						if ( iCount < 2 )
							iResult = 1;
						else
							iResult = strcmpi(ppCmd[0], ppCmd[1]);
					} break;

					case INTRINSIC_STRLEN:
					{
						iCount = 1;
						iResult = strlen(pszArgs);
					} break;

					case INTRINSIC_ISOBSCENE:
					{
						iCount = 1;
						iResult = g_Cfg.IsObscene( pszArgs );
					} break;
					case INTRINSIC_ISNUMBER:
					{
						iCount = 1;
						{
                            GETNONWHITESPACE( pszArgs );
                            if (*pszArgs == '-')
                                ++pszArgs;
							iResult = IsStrNumeric( pszArgs );
						}
					} break;

					case INTRINSIC_QVAL:
					{
						iCount = Str_ParseCmds( const_cast<tchar*>(pszArgs), ppCmd, 5, "," );
						if ( iCount < 3 )
							iResult = 0;
						else
						{
							llong a1 = GetSingle(ppCmd[0]);
							llong a2 = GetSingle(ppCmd[1]);
							if ( a1 < a2 )			iResult = GetSingle(ppCmd[2]);
							else if ( a1 == a2 )	iResult = ( iCount < 4 ) ? 0 : GetSingle(ppCmd[3]);
							else					iResult = ( iCount < 5 ) ? 0 : GetSingle(ppCmd[4]);
						}
					} break;

					case INTRINSIC_ABS:
					{
						iCount = 1;
						iResult = llabs(GetVal(pszArgs));
					} break;

					default:
						iCount = 0;
						iResult = 0;
						break;
				}

				pszArgs = pszArgsNext;

				if ( !iCount )
				{
					DEBUG_ERR(( "Bad intrinsic function usage: Missing arguments\n" ));
					return 0;
				}
				else
					return iResult;
			}
		}

		// Must be a symbol of some sort ?
        lpctstr ptcArgsOriginal = pszArgs;
		llong llVal;
		if ( m_VarGlobals.GetParseVal_Advance( pszArgs, &llVal ) )  // VAR.
			return llVal;
        if ( m_VarResDefs.GetParseVal( ptcArgsOriginal, &llVal ) )  // RESDEF.
            return llVal;
		if ( m_VarDefs.GetParseVal( ptcArgsOriginal, &llVal ) )     // DEF.
			return llVal;
	}
#pragma endregion intrinsics

	// hard end ! Error of some sort.
	tchar szTag[ EXPRESSION_MAX_KEY_LEN ];
	size_t i = GetIdentifierString( szTag, pszArgs );
	pszArgs += i;	// skip it.
	if ( strlen(orig) > 1)
		DEBUG_ERR(("Undefined symbol '%s' ['%s']\n", szTag, orig));
	else
		DEBUG_ERR(("Undefined symbol '%s'\n", szTag));
	return 0;
}