void CClient::addTargetVerb( LPCTSTR pszCmd, LPCTSTR pszArg ) { ADDTOCALLSTACK("CClient::addTargetVerb"); // Target a verb at some object . ASSERT(pszCmd); GETNONWHITESPACE(pszCmd); SKIP_SEPARATORS(pszCmd); if ( !strlen(pszCmd) ) pszCmd = pszArg; if ( pszCmd == pszArg ) { GETNONWHITESPACE(pszCmd); SKIP_SEPARATORS(pszCmd); pszArg = ""; } // priv here PLEVEL_TYPE ilevel = g_Cfg.GetPrivCommandLevel( pszCmd ); if ( ilevel > GetPrivLevel() ) return; m_Targ_Text.Format( "%s%s%s", pszCmd, ( pszArg[0] && pszCmd[0] ) ? " " : "", pszArg ); TCHAR * pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_TARGET_COMMAND), static_cast<LPCTSTR>(m_Targ_Text)); addTarget(CLIMODE_TARG_OBJ_SET, pszMsg); }
bool Str_Parse( TCHAR * pLine, TCHAR ** ppLine2, LPCTSTR pszSep ) { // Parse a list of args. Just get the next arg. // similar to strtok() // RETURN: true = the second arg is valid. if ( pszSep == NULL ) // default sep. pszSep = "=, \t"; // skip leading white space. TCHAR * pNonWhite = pLine; GETNONWHITESPACE(pNonWhite); if ( pNonWhite != pLine ) { memmove( pLine, pNonWhite, strlen( pNonWhite ) + 1 ); } TCHAR ch; bool bQuotes = false; for ( ; ; pLine++ ) { ch = *pLine; if ( ch == '"' ) // quoted argument { bQuotes = !bQuotes; continue; } if ( ch == '\0' ) // no args i guess. { if ( ppLine2 != NULL ) { *ppLine2 = pLine; } return false; } if ( strchr( pszSep, ch ) && (bQuotes == false)) break; } *pLine++ = '\0'; if ( IsSpace( ch )) // space separators might have other seps as well ? { GETNONWHITESPACE( pLine ); ch = *pLine; if ( ch && strchr( pszSep, ch )) { pLine++; } } // skip leading white space on args as well. if ( ppLine2 != NULL ) { *ppLine2 = Str_TrimWhitespace( pLine ); } return true; }
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; } }
void CScriptKeyAlloc::ParseKeyLate() { ADDTOCALLSTACK("CScriptKeyAlloc::ParseKeyLate"); ASSERT(m_pszKey); ParseKeyEnd(); GETNONWHITESPACE(m_pszKey); Str_Parse(m_pszKey, &m_pszArg); }
bool CResourceQty::Load(LPCTSTR &pszCmds) { ADDTOCALLSTACK("CResourceQty::Load"); // Can be either order.: // "Name Qty" or "Qty Name" const char *orig = pszCmds; GETNONWHITESPACE(pszCmds); // Skip leading spaces. m_iQty = LLONG_MIN; if ( !IsAlpha(*pszCmds) ) // might be { or . { m_iQty = Exp_GetVal(pszCmds); GETNONWHITESPACE(pszCmds); } if ( *pszCmds == '\0' ) { g_Log.EventError("Bad resource list element in '%s'\n", orig); return false; } m_rid = g_Cfg.ResourceGetID(RES_UNKNOWN, pszCmds); if ( m_rid.GetResType() == RES_UNKNOWN ) { g_Log.EventError("Bad resource list id '%s'\n", orig); return false; } GETNONWHITESPACE(pszCmds); if ( m_iQty == LLONG_MIN ) // trailing qty? { if ( *pszCmds == '\0' || *pszCmds == ',' ) m_iQty = 1; else { m_iQty = Exp_GetVal(pszCmds); GETNONWHITESPACE(pszCmds); } } return true; }
void CClient::addTargetFunction( LPCTSTR pszFunction, bool fAllowGround, bool fCheckCrime ) { ADDTOCALLSTACK("CClient::addTargetFunction"); // Target a verb at some object . ASSERT(pszFunction); GETNONWHITESPACE(pszFunction); SKIP_SEPARATORS(pszFunction); m_Targ_Text = pszFunction; addTarget( CLIMODE_TARG_OBJ_FUNC, "", fAllowGround, fCheckCrime ); }
bool CSVFile::OpenBase(void * pExtra) { ADDTOCALLSTACK("CSVFile::OpenBase"); if ( !PhysicalScriptFile::OpenBase(pExtra) ) return false; m_iCurrentRow = 0; // remove all empty lines so that we just have data rows stored for (std::vector<std::string>::iterator i = m_fileContent->begin(); i != m_fileContent->end(); ) { lpctstr pszLine = i->c_str(); GETNONWHITESPACE(pszLine); if ( *pszLine == '\0' ) i = m_fileContent->erase(i); else ++i; } // find the types and names of the columns tchar * ppColumnTypes[MAX_COLUMNS]; tchar * ppColumnNames[MAX_COLUMNS]; // first row tells us how many columns there are m_iColumnCount = ReadRowContent(ppColumnTypes, 0); if ( m_iColumnCount <= 0 ) { m_iColumnCount = 0; Close(); return false; } // second row lets us validate the column count if ( ReadRowContent(ppColumnNames, 1) != m_iColumnCount ) { m_iColumnCount = 0; Close(); return false; } // copy the names for (int i = 0; i < m_iColumnCount; i++) { m_pszColumnTypes[i] = new tchar[128]; strcpy(m_pszColumnTypes[i], ppColumnTypes[i]); m_pszColumnNames[i] = new tchar[128]; strcpy(m_pszColumnNames[i], ppColumnNames[i]); } m_pszColumnTypes[m_iColumnCount] = NULL; m_pszColumnNames[m_iColumnCount] = NULL; return true; }
void CClient::addTargetFunctionMulti(LPCTSTR pszFunction, ITEMID_TYPE itemid, HUE_TYPE wHue, bool fAllowGround) { ADDTOCALLSTACK("CClient::addTargetFunctionMulti"); // Target a verb at some object ASSERT(pszFunction); GETNONWHITESPACE(pszFunction); SKIP_SEPARATORS(pszFunction); m_Targ_Text = pszFunction; if ( CItemBase::IsID_Multi(itemid) ) // a multi we get from multi.mul { SetTargMode(CLIMODE_TARG_OBJ_FUNC); new PacketAddTarget(this, fAllowGround ? PacketAddTarget::Ground : PacketAddTarget::Object, CLIMODE_TARG_OBJ_FUNC, PacketAddTarget::None, itemid, wHue); } addTargetFunction(pszFunction, fAllowGround, false); }
DWORD ahextoi( LPCTSTR pszStr ) // Convert hex string to integer { // Unfortunatly the library func cant handle the number FFFFFFFF // TCHAR * sstop; return( strtol( s, &sstop, 16 )); if ( pszStr == NULL ) return 0; bool bHex = false; GETNONWHITESPACE(pszStr); if ( *pszStr == '0' ) { if (*++pszStr != '.') bHex = true; pszStr--; } DWORD val = 0; for (;;) { TCHAR ch = static_cast<TCHAR>(toupper(*pszStr)); if ( IsDigit(ch) ) ch -= '0'; else if ( bHex && ( ch >= 'A' ) && ( ch <= 'F' )) { ch -= 'A' - 10; } else if ( !bHex && ( ch == '.' ) ) { pszStr++; continue; } else break; val *= ( bHex ? 0x10 : 10 ); val += ch; pszStr ++; } return val; }
dword ahextoi( lpctstr pszStr ) // Convert hex string to integer { // Unfortunatly the library func cant handle the number FFFFFFFF // tchar * sstop; return( strtol( s, &sstop, 16 )); if ( pszStr == nullptr ) return 0; bool bHex = false; GETNONWHITESPACE(pszStr); if ( *pszStr == '0' ) { if (*++pszStr != '.') bHex = true; --pszStr; } dword val = 0; for (;;) { tchar ch = static_cast<tchar>(toupper(*pszStr)); if ( IsDigit(ch) ) ch -= '0'; else if ( bHex && ( ch >= 'A' ) && ( ch <= 'F' )) { ch -= 'A' - 10; } else if ( !bHex && ( ch == '.' ) ) { pszStr++; continue; } else break; val *= ( bHex ? 0x10 : 10 ); val += ch; pszStr ++; } return val; }
INT64 ahextoi64( LPCTSTR pszStr ) // Convert hex string to INT64 { if ( pszStr == NULL ) return 0; bool bHex = false; GETNONWHITESPACE(pszStr); if ( *pszStr == '0' ) { if (*++pszStr != '.') bHex = true; pszStr--; } INT64 val = 0; for (;;) { TCHAR ch = static_cast<TCHAR>(toupper(*pszStr)); if ( IsDigit(ch) ) ch -= '0'; else if ( bHex && ( ch >= 'A' ) && ( ch <= 'F' )) { ch -= 'A' - 10; } else if ( !bHex && ( ch == '.' ) ) { pszStr++; continue; } else break; val *= ( bHex ? 0x10 : 10 ); val += ch; pszStr ++; } return val; }
int64 ahextoi64( lpctstr pszStr ) // Convert hex string to int64 { if ( pszStr == nullptr ) return 0; bool bHex = false; GETNONWHITESPACE(pszStr); if ( *pszStr == '0' ) { if (*++pszStr != '.') bHex = true; --pszStr; } int64 val = 0; for (;;) { tchar ch = static_cast<tchar>(toupper(*pszStr)); if ( IsDigit(ch) ) ch -= '0'; else if ( bHex && ( ch >= 'A' ) && ( ch <= 'F' )) { ch -= 'A' - 10; } else if ( !bHex && ( ch == '.' ) ) { pszStr++; continue; } else break; val *= ( bHex ? 0x10 : 10 ); val += ch; ++pszStr; } return val; }
bool CScriptKeyAlloc::ParseKey( LPCTSTR pszKey ) { ADDTOCALLSTACK("CScriptKeyAlloc::ParseKey"); // Skip leading white space if ( ! pszKey ) { GetKeyBufferRaw(0); return false; } GETNONWHITESPACE( pszKey ); TCHAR * pBuffer = GetKeyBufferRaw( strlen( pszKey )); ASSERT(pBuffer); size_t iLen = m_Mem.GetDataLength() - 1; strncpy( pBuffer, pszKey, iLen ); pBuffer[iLen] = '\0'; Str_Parse( pBuffer, &m_pszArg ); return( true ); }
bool CWebPageDef::WebPageUpdate( bool fNow, LPCTSTR pszDstName, CTextConsole * pSrc ) { ADDTOCALLSTACK("CWebPageDef::WebPageUpdate"); // Generate the status web pages. // Read in the Base status page "*STATUSBASE.HTM" // Filter the XML type tags. // Output the status page "*.HTM" // Server name // Server email // Number of clients, items, NPC's if ( ! fNow ) { if ( m_iUpdatePeriod <= 0 ) return false; if ( CServTime::GetCurrentTime() < m_timeNextUpdate ) return true; // should stilll be valid } ASSERT(pSrc); m_timeNextUpdate = CServTime::GetCurrentTime() + m_iUpdatePeriod; if ( pszDstName == NULL ) { pszDstName = m_sDstFilePath; } if ( m_type != WEBPAGE_TEMPLATE || *pszDstName == '\0' || m_sSrcFilePath.IsEmpty()) return false; CScript FileRead; if ( ! FileRead.Open( m_sSrcFilePath, OF_READ|OF_TEXT|OF_DEFAULTMODE )) { return false; } CScriptFileContext context( &FileRead ); // set this as the context. CFileConsole FileOut; if ( ! FileOut.m_FileOut.Open( pszDstName, OF_WRITE|OF_TEXT )) { DEBUG_ERR(( "Can't open web page output '%s'\n", static_cast<LPCTSTR>(pszDstName) )); return false; } bool fScriptMode = false; while ( FileRead.ReadTextLine( false )) { TCHAR *pszTmp = Str_GetTemp(); strcpy( pszTmp, FileRead.GetKey()); TCHAR * pszHead = strstr( pszTmp, "<script language=\"Sphere\">" ); if ( pszHead != NULL ) { // Deal with the stuff preceding the scripts. *pszHead = '\0'; pszHead += 26; ParseText( pszTmp, pSrc, 1 ); FileOut.SysMessage( pszTmp ); fScriptMode = true; } else { pszHead = pszTmp; } // Look for the end of </script> if ( fScriptMode ) { GETNONWHITESPACE(pszHead); TCHAR * pszFormat = pszHead; pszHead = strstr( pszFormat, "</script>" ); if ( pszHead != NULL ) { *pszHead = '\0'; pszHead += 9; fScriptMode = false; } if ( pszFormat[0] != '\0' ) { // Allow if/then logic ??? OnTriggerRun( CScript &s, TRIGRUN_SINGLE_EXEC, &FileOut ) CScript script( pszFormat ); if ( ! r_Verb( script, &FileOut )) { DEBUG_ERR(( "Web page source format error '%s'\n", static_cast<LPCTSTR>(pszTmp) )); continue; } } if ( fScriptMode ) continue; } // Look for stuff we can displace here. %STUFF% ParseText( pszHead, pSrc, 1 ); FileOut.SysMessage( pszHead ); } return( true ); }
int CScriptObj::ParseText( TCHAR * pszResponse, CTextConsole * pSrc, int iFlags, CScriptTriggerArgs * pArgs ) { // Take in a line of text that may have fields that can be replaced with operators here. // ex. "SPEAK hello there my friend <SRC.NAME> my name is <NAME>" // ARGS: // iFlags = 2=Allow recusive bracket count. 1=use HTML %% as the delimiters. // NOTE: // html will have opening <script language="GRAY_FILE"> and then closing </script> // RETURN: // New length of the string. // // Parsing flags LPCTSTR pszKey; // temporary, set below bool fRes; static LPCTSTR const m_ExcKeys[] = { "too many entrances", "CALLing subfunction", "writing value", "memcpy/memmove", }; static int sm_iReentrant = 0; static bool sm_fBrackets = false; // allowed to span multi lines. if ( ! (iFlags&2)) { // DEBUG_CHECK(!sm_iReentrant); sm_fBrackets = false; } int iBegin = 0; TCHAR chBegin = '<'; TCHAR chEnd = '>'; bool fHTML = (iFlags&1); if ( fHTML ) { chBegin = '%'; chEnd = '%'; } int i; EXC_TRY(("ParseText('%s',%x,%i,%x)", pszResponse, pSrc, iFlags, pArgs)); for ( i = 0; pszResponse[i]; i++ ) { TCHAR ch = pszResponse[i]; if ( ! sm_fBrackets ) // not in brackets { if ( ch == chBegin ) // found the start ! { if ( !( isalnum( pszResponse[i+1] ) || pszResponse[i+1] == '<' ) ) // ignore this. continue; iBegin = i; sm_fBrackets = true; } continue; } if ( ch == '<' ) // recursive brackets { if ( !( isalnum( pszResponse[i+1] ) || pszResponse[i+1] == '<' ) ) // ignore this. continue; if (sm_iReentrant > 32 ) { EXC_SET(m_ExcKeys[0]); ASSERT( sm_iReentrant < 32 ); } sm_iReentrant++; sm_fBrackets = false; int ilen = ParseText( pszResponse+i, pSrc, 2, pArgs ); sm_fBrackets = true; sm_iReentrant--; i += ilen; // DEBUG_CHECK( ilen < 256 ); continue; } if ( ch == chEnd ) { sm_fBrackets = false; pszResponse[i] = '\0'; CGString sVal; pszKey = (LPCTSTR) pszResponse+iBegin+1; if ( !strnicmp( pszKey, "CALL", 4 ) && isspace(pszKey[4]) ) { EXC_SET(m_ExcKeys[1]); pszKey += 4; GETNONWHITESPACE( pszKey ); LPCTSTR pszArgs = strchr( pszKey, ' ' ); if ( pszArgs ) GETNONWHITESPACE( pszArgs ); if ( !pszArgs || !*pszArgs ) { fRes = this->r_Call( pszKey, pSrc, pArgs, &sVal ); } else { CScriptTriggerArgs Args( pszArgs ); if ( pArgs ) Args.m_VarsLocal = pArgs->m_VarsLocal; fRes = this->r_Call( pszKey, pSrc, &Args, &sVal ); if ( pArgs ) pArgs->m_VarsLocal = Args.m_VarsLocal; } } else { if ( !strnicmp( pszKey, "SRC", 3 ) && pszKey[3] == '\0' ) { pszKey = pszKey; } EXC_SET(m_ExcKeys[2]); if ( !( fRes = r_WriteVal( pszKey, sVal, pSrc ) ) ) { EXC_SET(m_ExcKeys[2]); if ( pArgs && pArgs->r_WriteVal( pszKey, sVal, pSrc ) ) fRes = true; } } if ( !fRes ) { DEBUG_ERR(( "Can't resolve <%s>\n", pszKey )); // Just in case this really is a <= operator ? pszResponse[i] = chEnd; // continue; // by Kell } resolved: if ( sVal.IsEmpty() && fHTML ) { sVal = " "; } int len = sVal.GetLength(); EXC_SET(m_ExcKeys[3]); memmove( pszResponse+iBegin+len, pszResponse+i+1, strlen( pszResponse+i+1 ) + 1 ); EXC_SET(m_ExcKeys[3]); memcpy( pszResponse+iBegin, (LPCTSTR) sVal, len ); i = iBegin+len-1; if ( iFlags&2 ) // just do this one then bail out. return( i ); } } EXC_CATCH("Script parse text"); return( i ); }
TCHAR * Str_TrimWhitespace( TCHAR * pStr ) { GETNONWHITESPACE( pStr ); Str_TrimEndWhitespace( pStr, strlen(pStr)); return( pStr ); }
bool CRegionBase::MakeRegionName() { ADDTOCALLSTACK("CRegionBase::MakeRegionName"); if ( m_pDefName ) return true; TCHAR ch; LPCTSTR pszKey = NULL; // auxiliary, the key of a similar CVarDef, if any found TCHAR * pbuf = Str_GetTemp(); TCHAR * pszDef = pbuf + 2; strcpy(pbuf, "a_"); LPCTSTR pszName = GetName(); GETNONWHITESPACE( pszName ); if ( !strnicmp( "the ", pszName, 4 ) ) pszName += 4; else if ( !strnicmp( "a ", pszName, 2 ) ) pszName += 2; else if ( !strnicmp( "an ", pszName, 3 ) ) pszName += 3; else if ( !strnicmp( "ye ", pszName, 3 ) ) pszName += 3; for ( ; *pszName; pszName++ ) { if ( !strnicmp( " of ", pszName, 4 ) || !strnicmp( " in ", pszName, 4 ) ) { pszName += 4; continue; } if ( !strnicmp( " the ", pszName, 5 ) ) { pszName += 5; continue; } ch = *pszName; if ( ch == ' ' || ch == '\t' || ch == '-' ) ch = '_'; else if ( !isalnum( ch ) ) continue; // collapse multiple spaces together if ( ch == '_' && *(pszDef-1) == '_' ) continue; *pszDef = static_cast<TCHAR>(tolower(ch)); pszDef++; } *pszDef = '_'; *(++pszDef) = '\0'; size_t iMax = g_Cfg.m_RegionDefs.GetCount(); int iVar = 1; size_t iLen = strlen( pbuf ); for ( size_t i = 0; i < iMax; i++ ) { CRegionBase * pRegion = dynamic_cast <CRegionBase*> (g_Cfg.m_RegionDefs.GetAt(i)); if ( !pRegion ) continue; pszKey = pRegion->GetResourceName(); if ( !pszKey ) continue; // Is this a similar key? if ( strnicmp( pbuf, pszKey, iLen ) != 0 ) continue; // skip underscores pszKey = pszKey + iLen; while ( *pszKey == '_' ) pszKey++; // Is this is subsequent key with a number? Get the highest (plus one) if ( IsStrNumericDec( pszKey ) ) { int iVarThis = ATOI( pszKey ); if ( iVarThis >= iVar ) iVar = iVarThis + 1; } else iVar++; } // Only one, no need for the extra "_" sprintf( pszDef, "%i", iVar ); SetResourceName( pbuf ); // Assign name return true; }
bool CResourceDef::MakeResourceName() { ADDTOCALLSTACK("CResourceDef::MakeResourceName"); if ( m_pDefName ) return true; LPCTSTR pszName = GetName(); GETNONWHITESPACE( pszName ); TCHAR * pbuf = Str_GetTemp(); TCHAR ch; TCHAR * pszDef; strcpy(pbuf, "a_"); LPCTSTR pszKey = NULL; // auxiliary, the key of a similar CVarDef, if any found pszDef = pbuf + 2; for ( ; *pszName; pszName++ ) { ch = *pszName; if ( ch == ' ' || ch == '\t' || ch == '-' ) ch = '_'; else if ( !isalnum( ch ) ) continue; // collapse multiple spaces together if ( ch == '_' && *(pszDef-1) == '_' ) continue; *pszDef = ch; pszDef++; } *pszDef = '_'; *(++pszDef) = '\0'; size_t iMax = g_Exp.m_VarDefs.GetCount(); int iVar = 1; size_t iLen = strlen( pbuf ); for ( size_t i = 0; i < iMax; i++ ) { // Is this a similar key? pszKey = g_Exp.m_VarDefs.GetAt(i)->GetKey(); if ( strnicmp( pbuf, pszKey, iLen ) != 0 ) continue; // skip underscores pszKey = pszKey + iLen; while ( *pszKey == '_' ) pszKey++; // Is this is subsequent key with a number? Get the highest (plus one) if ( IsStrNumericDec( pszKey ) ) { int iVarThis = ATOI( pszKey ); if ( iVarThis >= iVar ) iVar = iVarThis + 1; } else iVar++; } // add an extra _, hopefully won't conflict with named areas sprintf( pszDef, "_%i", iVar ); SetResourceName( pbuf ); // Assign name return true; }
bool CChar::NPC_OnHearPetCmd( LPCTSTR pszCmd, CChar *pSrc, bool fAllPets ) { ADDTOCALLSTACK("CChar::NPC_OnHearPetCmd"); // This should just be another speech block !!! // We own this char (pet or hireling) // pObjTarget = the m_ActTarg has been set for them to attack. // RETURN: // true = we understand this. tho we may not do what we are told. // false = this is not a command we know. // if ( GetTargMode() == CLIMODE_TARG_PET_CMD ) it needs a target. if ( !pSrc->IsClient() || m_pPlayer || !m_pNPC ) return false; m_fIgnoreNextPetCmd = false; // We clear this incase it's true from previous pet cmds. TALKMODE_TYPE mode = TALKMODE_SAY; if ( OnTriggerSpeech(true, pszCmd, pSrc, mode) ) { m_fIgnoreNextPetCmd = !fAllPets; return true; } static LPCTSTR const sm_Pet_table[] = { "ATTACK", "BOUGHT", "CASH", "COME", "DROP", // "GIVE" ? "DROP ALL", "EQUIP", "FOLLOW", "FOLLOW ME", "FRIEND", "GO", "GUARD", "GUARD ME", "KILL", "PRICE", // may have args ? "RELEASE", "SAMPLES", "SPEAK", "STATUS", "STAY", "STOCK", "STOP", "TRANSFER", "UNFRIEND" }; PC_TYPE iCmd = static_cast<PC_TYPE>(FindTableSorted(pszCmd, sm_Pet_table, COUNTOF(sm_Pet_table))); if ( iCmd < 0 ) { if ( !strnicmp(pszCmd, sm_Pet_table[PC_PRICE], 5) ) iCmd = PC_PRICE; else return false; } switch ( iCmd ) { case PC_FOLLOW: case PC_STAY: case PC_STOP: { // Pet friends can use only these commands if ( Memory_FindObjTypes(pSrc, MEMORY_FRIEND) ) break; } default: { // All others commands are avaible only to pet owner if ( !NPC_IsOwnedBy(pSrc, true) ) return false; } } if ( IsStatFlag(STATF_DEAD) ) { // Bonded NPCs still placed on world even when dead. // They can listen to commands, but not to these commands below if ( iCmd == PC_GUARD || iCmd == PC_GUARD_ME || iCmd == PC_ATTACK || iCmd == PC_KILL || iCmd == PC_TRANSFER || iCmd == PC_DROP || iCmd == PC_DROP_ALL ) return true; } bool bTargAllowGround = false; bool bCheckCrime = false; LPCTSTR pTargPrompt = NULL; CCharBase *pCharDef = Char_GetDef(); switch ( iCmd ) { case PC_ATTACK: case PC_KILL: pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_ATT); bCheckCrime = true; break; case PC_COME: case PC_GUARD_ME: case PC_FOLLOW_ME: m_Act_Targ = pSrc->GetUID(); Skill_Start(NPCACT_FOLLOW_TARG); break; case PC_FOLLOW: pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FOLLOW); break; case PC_FRIEND: if ( IsStatFlag(STATF_Conjured) ) { pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND_SUMMONED)); return false; } pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_FRIEND); break; case PC_UNFRIEND: pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_UNFRIEND); break; case PC_GO: pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_GO); bTargAllowGround = true; break; case PC_GUARD: pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_GUARD); bCheckCrime = true; break; case PC_STAY: case PC_STOP: Skill_Start(NPCACT_STAY); break; case PC_TRANSFER: if ( IsStatFlag(STATF_Conjured) ) { pSrc->SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_TRANSFER_SUMMONED)); return true; } pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_TARG_TRANSFER); break; case PC_RELEASE: SoundChar(CRESND_RAND2); if ( IsStatFlag(STATF_Conjured) || (m_pNPC->m_bonded && IsStatFlag(STATF_DEAD)) ) { Delete(); return true; } Skill_Start(SKILL_NONE); NPC_PetClearOwners(); ResendTooltip(); break; case PC_DROP: { // Drop backpack items on ground // NOTE: This is also called on pet release CItemContainer *pPack = GetPack(); if ( pPack ) { pPack->ContentsDump(GetTopPoint(), ATTR_OWNED); break; } if ( NPC_CanSpeak() ) Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_CARRYNOTHING)); return true; } case PC_DROP_ALL: DropAll(NULL, ATTR_OWNED); break; case PC_SPEAK: NPC_OnPetCommand(true, pSrc); return true; case PC_EQUIP: ItemEquipWeapon(false); ItemEquipArmor(false); break; case PC_STATUS: { if ( !NPC_CanSpeak() ) break; unsigned int iWage = pCharDef->GetHireDayWage(); CItemContainer *pBank = GetBank(); TCHAR *pszMsg = Str_GetTemp(); if ( NPC_IsVendor() ) { CItemContainer *pCont = GetBank(LAYER_VENDOR_STOCK); TCHAR *pszTemp1 = Str_GetTemp(); TCHAR *pszTemp2 = Str_GetTemp(); TCHAR *pszTemp3 = Str_GetTemp(); if ( iWage ) { sprintf(pszTemp1, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_STAT_GOLD_1), pBank->m_itEqBankBox.m_Check_Amount); sprintf(pszTemp2, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_STAT_GOLD_2), pBank->m_itEqBankBox.m_Check_Amount / iWage); sprintf(pszTemp3, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_STAT_GOLD_3), static_cast<int>(pCont->GetCount())); } else { sprintf(pszTemp1, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_STAT_GOLD_1), pBank->m_itEqBankBox.m_Check_Amount); sprintf(pszTemp2, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_STAT_GOLD_4), pBank->m_itEqBankBox.m_Check_Restock, pBank->GetTimerAdjusted() / 60); sprintf(pszTemp3, g_Cfg.GetDefaultMsg(DEFMSG_NPC_VENDOR_STAT_GOLD_3), static_cast<int>(pCont->GetCount())); } sprintf(pszMsg, "%s %s %s", pszTemp1, pszTemp2, pszTemp3); } else if ( iWage ) { sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_DAYS_LEFT), pBank->m_itEqBankBox.m_Check_Amount / iWage); } Speak(pszMsg); return true; } case PC_CASH: { // Give up my cash total. if ( !NPC_IsVendor() ) return false; CItemContainer *pBank = GetBank(); if ( pBank ) { unsigned int iWage = pCharDef->GetHireDayWage(); TCHAR *pszMsg = Str_GetTemp(); if ( pBank->m_itEqBankBox.m_Check_Amount > iWage ) { sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_GETGOLD_1), pBank->m_itEqBankBox.m_Check_Amount - iWage); pSrc->AddGoldToPack(pBank->m_itEqBankBox.m_Check_Amount - iWage); pBank->m_itEqBankBox.m_Check_Amount = iWage; } else sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_GETGOLD_2), pBank->m_itEqBankBox.m_Check_Amount); Speak(pszMsg); } return true; } case PC_BOUGHT: if ( !NPC_IsVendor() ) return false; Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_ITEMS_BUY)); pSrc->GetClient()->addBankOpen(this, LAYER_VENDOR_EXTRA); break; case PC_PRICE: if ( !NPC_IsVendor() ) return false; pTargPrompt = g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_SETPRICE); break; case PC_SAMPLES: if ( !NPC_IsVendor() ) return false; Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_ITEMS_SAMPLE)); pSrc->GetClient()->addBankOpen(this, LAYER_VENDOR_BUYS); break; case PC_STOCK: // Magic restocking container. if ( !NPC_IsVendor() ) return false; Speak(g_Cfg.GetDefaultMsg(DEFMSG_NPC_PET_ITEMS_SELL)); pSrc->GetClient()->addBankOpen(this, LAYER_VENDOR_STOCK); break; default: return false; } if ( pTargPrompt ) { pszCmd += strlen(sm_Pet_table[iCmd]); GETNONWHITESPACE(pszCmd); pSrc->m_pClient->m_tmPetCmd.m_iCmd = iCmd; pSrc->m_pClient->m_tmPetCmd.m_fAllPets = fAllPets; pSrc->m_pClient->m_Targ_UID = GetUID(); pSrc->m_pClient->m_Targ_Text = pszCmd; pSrc->m_pClient->addTarget(CLIMODE_TARG_PET_CMD, pTargPrompt, bTargAllowGround, bCheckCrime); return true; } // Make some sound to confirm we heard it NPC_OnPetCommand(true, pSrc); return true; }
size_t CServerDef::StatGet(SERV_STAT_TYPE i) const { ADDTOCALLSTACK("CServerDef::StatGet"); ASSERT( i >= 0 && i <= SERV_STAT_QTY ); size_t d = m_stStat[i]; EXC_TRY("StatGet"); if ( i == SERV_STAT_MEM ) // memory information { d = 0; if ( m_bPmemory ) { #ifdef _WIN32 if ( !m_hmPsapiDll ) // try to load psapi.dll if not loaded yet { EXC_SET("load process info"); m_hmPsapiDll = LoadLibrary(TEXT("psapi.dll")); if (m_hmPsapiDll == NULL) { m_bPmemory = false; g_Log.EventError(("Unable to load process information PSAPI.DLL library. Memory information will be not available.\n")); } else m_GetProcessMemoryInfo = reinterpret_cast<pGetProcessMemoryInfo>(::GetProcAddress(m_hmPsapiDll,"GetProcessMemoryInfo")); } if ( m_GetProcessMemoryInfo ) { EXC_SET("open process"); HANDLE hProcess = GetCurrentProcess(); if ( hProcess ) { ASSERT( hProcess == (HANDLE)-1 ); EXC_SET("get memory info"); if ( m_GetProcessMemoryInfo(hProcess, &pcnt, sizeof(pcnt)) ) { EXC_SET("read memory info"); d = pcnt.WorkingSetSize; } CloseHandle(hProcess); } } #else struct rusage usage; int res = getrusage(RUSAGE_SELF, &usage); if ( res == 0 && usage.ru_idrss ) d = usage.ru_idrss; else { CSFileText inf; tchar * buf = Str_GetTemp(), * head; sprintf(buf, "/proc/%d/status", getpid()); if ( inf.Open(buf, OF_READ|OF_TEXT) ) { for (;;) { if ( !inf.ReadString(buf, SCRIPT_MAX_LINE_LEN) ) break; if ( (head = strstr(buf, "VmSize:")) != NULL ) { head += 7; GETNONWHITESPACE(head) d = ATOI(head) * 1000; break; } } inf.Close(); } } if ( !d ) { g_Log.EventError(("Unable to load process information from getrusage() and procfs. Memory information will be not available.\n")); m_bPmemory = false; } #endif if ( d != 0 ) d /= 1024; } } return d; EXC_CATCH; EXC_DEBUG_START; g_Log.EventDebug("stat '%d', val '%" PRIuSIZE_T "'\n", i, d); EXC_DEBUG_END; return 0; }
bool CMenuItem::ParseLine( TCHAR * pszArgs, CScriptObj * pObjBase, CTextConsole * pSrc ) { ADDTOCALLSTACK("CMenuItem::ParseLine"); if ( *pszArgs == '@' ) { // This allows for triggers in menus return false; } TCHAR * pszArgStart = pszArgs; while ( _ISCSYM( *pszArgs )) pszArgs++; if ( *pszArgs ) { *pszArgs = '\0'; pszArgs++; GETNONWHITESPACE( pszArgs ); } // The item id (if we want to have an item type menu) or 0 if ( strcmp( pszArgStart, "0" ) != 0 ) { CItemBase * pItemBase = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(g_Cfg.ResourceGetIndexType( RES_ITEMDEF, pszArgStart ))); if ( pItemBase != NULL ) { m_id = static_cast<WORD>(pItemBase->GetDispID()); pObjBase = pItemBase; } else { DEBUG_ERR(( "Bad MENU item id '%s'\n", pszArgStart )); return( false ); // skip this. } } else { m_id = 0; } if ( pObjBase != NULL ) { pObjBase->ParseText( pszArgs, pSrc ); } else { g_Serv.ParseText( pszArgs, pSrc ); } // Parsing @color if ( *pszArgs == '@' ) { pszArgs++; HUE_TYPE wHue = static_cast<HUE_TYPE>(Exp_GetVal( pszArgs )); if ( wHue != 0 ) wHue = (wHue == 1? 0x7FF: wHue-1); m_color = wHue; SKIP_ARGSEP( pszArgs ); } else m_color = 0; m_sText = pszArgs; if ( m_sText.IsEmpty()) { if ( pObjBase ) // use the objects name by default. { m_sText = pObjBase->GetName(); if ( ! m_sText.IsEmpty()) return( true ); } DEBUG_ERR(( "Bad MENU item text '%s'\n", pszArgStart )); } return( !m_sText.IsEmpty() ); }
bool CScriptObj::r_Call( LPCTSTR pszFunction, CTextConsole * pSrc, CScriptTriggerArgs * pArgs, CGString * psVal, TRIGRET_TYPE * piRet ) { GETNONWHITESPACE( pszFunction ); int index; { int iCompareRes = -1; index = g_Cfg.m_Functions.FindKeyNear( pszFunction, iCompareRes, true ); if ( iCompareRes ) index = -1; } if ( index < 0 ) return false; CResourceNamed * pFunction = STATIC_CAST <CResourceNamed *>( g_Cfg.m_Functions[index] ); ASSERT(pFunction); CResourceLock sFunction; if ( pFunction->ResourceLock(sFunction) ) { TScriptProfiler::TScriptProfilerFunction *pFun; LONGLONG ticks, ticksend; // If functions profiler is on, search this function record and get pointer to it // if not, create the corresponding record if ( IsSetEF(EF_Script_Profiler) ) { char *pName = Str_GetTemp(); char *pSpace; // lowercase for speed, and strip arguments strcpy(pName, pszFunction); if ( pSpace = strchr(pName, ' ') ) *pSpace = 0; _strlwr(pName); if ( g_profiler.initstate != 0xf1 ) // it is not initalised { memset(&g_profiler, 0, sizeof(g_profiler)); g_profiler.initstate = (unsigned char)0xf1; // '' } for ( pFun = g_profiler.FunctionsHead; pFun != NULL; pFun = pFun->next ) { if ( !strcmp(pFun->name, pName) ) break; } // first time function called. so create a record for it if ( !pFun ) { pFun = new TScriptProfiler::TScriptProfilerFunction; memset(pFun, 0, sizeof(TScriptProfiler::TScriptProfilerFunction)); strcpy(pFun->name, pName); if ( g_profiler.FunctionsTail ) g_profiler.FunctionsTail->next = pFun; else g_profiler.FunctionsHead = pFun; g_profiler.FunctionsTail = pFun; } // prepare the informational block pFun->called++; g_profiler.called++; #ifdef _WIN32 if ( ! QueryPerformanceCounter((LARGE_INTEGER *) &ticks )) ticks = GetTickCount(); #else ticks = GetTickCount(); // our own function #endif } TRIGRET_TYPE iRet =OnTriggerRun( sFunction, TRIGRUN_SECTION_TRUE, pSrc, pArgs, IsSetEF( EF_Scripts_Ret_Strings ) ? psVal : NULL ); if ( IsSetEF(EF_Script_Profiler) ) { // update the time call information #ifdef _WIN32 if ( ! QueryPerformanceCounter((LARGE_INTEGER *) &ticksend )) ticksend = GetTickCount(); #else ticksend = GetTickCount(); // our own function #endif ticks = ticksend - ticks; pFun->total += ticks; pFun->average = (pFun->total/pFun->called); if ( pFun->max < ticks ) pFun->max = ticks; if (( pFun->min > ticks ) || ( !pFun->min )) pFun->min = ticks; g_profiler.total += ticks; } if ( psVal && !IsSetEF( EF_Scripts_Ret_Strings ) ) psVal->FormatVal( iRet ); if ( piRet ) *piRet = iRet; } return( true ); }
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; }
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; }
bool CServerDef::r_WriteVal( lpctstr pszKey, CSString &sVal, CTextConsole * pSrc ) { ADDTOCALLSTACK("CServerDef::r_WriteVal"); EXC_TRY("WriteVal"); switch ( FindTableSorted( pszKey, sm_szLoadKeys, CountOf( sm_szLoadKeys )-1 ) ) { case SC_ACCAPP: sVal.FormatVal( m_eAccApp ); break; case SC_ACCAPPS: // enum string ASSERT( m_eAccApp >= 0 && m_eAccApp < ACCAPP_QTY ); sVal = sm_AccAppTable[ m_eAccApp ]; break; case SC_ADMINEMAIL: sVal = m_sEMail; break; case SC_AGE: // display the age in days. sVal.FormatLLVal( GetAgeHours()/24 ); break; case SC_CLIENTVERSION: { char szVersion[ 128 ]; sVal = m_ClientVersion.WriteClientVer( szVersion ); } break; case SC_CREATE: sVal.FormatLLVal( -( g_World.GetTimeDiff(m_timeCreate) / TICK_PER_SEC ) ); break; case SC_LANG: sVal = m_sLang; break; case SC_LASTVALIDDATE: if ( m_timeLastValid.IsTimeValid() ) sVal.FormatLLVal( GetTimeSinceLastValid() / ( TICK_PER_SEC * 60 ) ); else sVal = "NA"; break; case SC_LASTVALIDTIME: // How many seconds ago. sVal.FormatLLVal( m_timeLastValid.IsTimeValid() ? ( GetTimeSinceLastValid() / TICK_PER_SEC ) : -1 ); break; case SC_SERVIP: sVal = m_ip.GetAddrStr(); break; case SC_NAME: case SC_SERVNAME: sVal = GetName(); // What the name should be. Fill in from ping. break; case SC_SERVPORT: sVal.FormatVal( m_ip.GetPort() ); break; case SC_ACCOUNTS: sVal.FormatSTVal( StatGet( SERV_STAT_ACCOUNTS ) ); break; case SC_CLIENTS: sVal.FormatSTVal( StatGet( SERV_STAT_CLIENTS ) ); break; case SC_ITEMS: sVal.FormatSTVal( StatGet( SERV_STAT_ITEMS ) ); break; case SC_MEM: sVal.FormatSTVal( StatGet( SERV_STAT_MEM ) ); break; case SC_CHARS: sVal.FormatSTVal( StatGet( SERV_STAT_CHARS ) ); break; case SC_TIMEZONE: sVal.FormatVal( m_TimeZone ); break; case SC_URL: sVal = m_sURL; break; case SC_URLLINK: // try to make a link of it. if ( m_sURL.IsEmpty() ) { sVal = GetName(); break; } sVal.Format("<a href=\"http://%s\">%s</a>", static_cast<lpctstr>(m_sURL), GetName()); break; case SC_VERSION: sVal = SPHERE_VERSION; break; default: { lpctstr pszArgs = strchr(pszKey, ' '); if (pszArgs != NULL) GETNONWHITESPACE(pszArgs); CScriptTriggerArgs Args( pszArgs ? pszArgs : "" ); if ( r_Call( pszKey, pSrc, &Args, &sVal ) ) return true; return CScriptObj::r_WriteVal( pszKey, sVal, pSrc ); } } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }
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 ); }
llong CExpression::GetValMath( llong llVal, lpctstr & pExpr ) { ADDTOCALLSTACK("CExpression::GetValMath"); GETNONWHITESPACE(pExpr); // Look for math type operator. switch ( pExpr[0] ) { case '\0': break; case ')': // expression end markers. case '}': case ']': ++pExpr; // consume this. break; case '+': ++pExpr; llVal += GetVal( pExpr ); break; case '-': ++pExpr; llVal -= GetVal( pExpr ); break; case '*': ++pExpr; llVal *= GetVal( pExpr ); break; case '|': ++pExpr; if ( pExpr[0] == '|' ) // boolean ? { ++pExpr; llVal = ( GetVal( pExpr ) || llVal ); } else // bitwise llVal |= GetVal( pExpr ); break; case '&': ++pExpr; if ( pExpr[0] == '&' ) // boolean ? { ++pExpr; llVal = ( GetVal( pExpr ) && llVal ); // tricky stuff here. logical ops must come first or possibly not get processed. } else // bitwise llVal &= GetVal( pExpr ); break; case '/': ++pExpr; { llong iVal = GetVal( pExpr ); if ( ! iVal ) { g_Log.EventError("Evaluating math: Divide by 0\n"); break; } llVal /= iVal; } break; case '%': ++pExpr; { llong iVal = GetVal( pExpr ); if ( ! iVal ) { g_Log.EventError("Evaluating math: Modulo 0\n"); break; } llVal %= iVal; } break; case '^': ++pExpr; llVal ^= GetVal(pExpr); break; case '>': // boolean ++pExpr; if ( pExpr[0] == '=' ) // boolean ? { ++pExpr; llVal = ( llVal >= GetVal( pExpr ) ); } else if ( pExpr[0] == '>' ) // shift { ++pExpr; llVal >>= GetVal( pExpr ); } else
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; }
bool CClient::r_WriteVal( LPCTSTR pszKey, CGString & sVal, CTextConsole * pSrc ) { ADDTOCALLSTACK("CClient::r_WriteVal"); EXC_TRY("WriteVal"); int index; if ( !strnicmp("CTAG.", pszKey, 5) ) // CTAG.xxx - client tag { if ( pszKey[4] != '.' ) return( false ); pszKey += 5; CVarDefCont *vardef = m_TagDefs.GetKey(pszKey); sVal = vardef ? vardef->GetValStr() : ""; return true; } if ( !strnicmp("CTAG0.", pszKey, 6) ) // CTAG0.xxx - client tag { if ( pszKey[5] != '.' ) return( false ); pszKey += 6; CVarDefCont *vardef = m_TagDefs.GetKey(pszKey); sVal = vardef ? vardef->GetValStr() : "0"; return true; } if ( !strnicmp( "TARGP", pszKey, 5 ) && ( pszKey[5] == '\0' || pszKey[5] == '.' ) ) index = CC_TARGP; else if ( !strnicmp( "SCREENSIZE", pszKey, 10 ) && ( pszKey[10] == '\0' || pszKey[10] == '.' ) ) index = CC_SCREENSIZE; else if ( !strnicmp( "REPORTEDCLIVER", pszKey, 14 ) && ( pszKey[14] == '\0' || pszKey[14] == '.' ) ) index = CC_REPORTEDCLIVER; else index = FindTableSorted( pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys)-1 ); switch (index) { case CC_ALLMOVE: sVal.FormatVal( IsPriv( PRIV_ALLMOVE )); break; case CC_ALLSHOW: sVal.FormatVal( IsPriv( PRIV_ALLSHOW )); break; case CC_CLIENTIS3D: sVal.FormatVal( GetNetState()->isClient3D() ); break; case CC_CLIENTISKR: sVal.FormatVal( GetNetState()->isClientKR() ); break; case CC_CLIENTISSA: sVal.FormatVal( GetNetState()->isClientSA() ); break; case CC_CLIENTVERSION: { TCHAR szVersion[ 128 ]; sVal = m_Crypt.WriteClientVer( szVersion ); } break; case CC_DEBUG: sVal.FormatVal( IsPriv( PRIV_DEBUG )); break; case CC_DETAIL: sVal.FormatVal( IsPriv( PRIV_DETAIL )); break; case CC_GM: // toggle your GM status on/off sVal.FormatVal( IsPriv( PRIV_GM )); break; case CC_HEARALL: sVal.FormatVal( IsPriv( PRIV_HEARALL )); break; case CC_LASTEVENT: sVal.FormatLLVal( m_timeLastEvent.GetTimeRaw() ); break; case CC_PRIVSHOW: // Show my priv title. sVal.FormatVal( ! IsPriv( PRIV_PRIV_NOSHOW )); break; case CC_REPORTEDCLIVER: { pszKey += strlen(sm_szLoadKeys[index]); GETNONWHITESPACE( pszKey ); int iCliVer = (GetNetState()->getReportedVersion() & 0xFFFFFF0); if ( pszKey[0] != '\0' ) iCliVer = GetNetState()->getReportedVersion(); TCHAR szVersion[128]; sVal = CCrypt::WriteClientVerString( iCliVer, szVersion ); } break; case CC_SCREENSIZE: { if ( pszKey[10] == '.' ) { pszKey += strlen(sm_szLoadKeys[index]); SKIP_SEPARATORS(pszKey); if ( !strnicmp("X", pszKey, 1) ) sVal.Format( "%lu", m_ScreenSize.x ); else if ( !strnicmp("Y", pszKey, 1) ) sVal.Format( "%lu", m_ScreenSize.y ); else return( false ); } else sVal.Format( "%lu,%lu", m_ScreenSize.x, m_ScreenSize.y ); } break; case CC_TARG: sVal.FormatHex(m_Targ_UID); break; case CC_TARGP: if ( pszKey[5] == '.' ) { return m_Targ_p.r_WriteVal( pszKey+6, sVal ); } sVal = m_Targ_p.WriteUsed(); break; case CC_TARGPROP: sVal.FormatHex(m_Prop_UID); break; case CC_TARGPRV: sVal.FormatHex(m_Targ_PrvUID); break; case CC_TARGTXT: sVal = m_Targ_Text; break; default: return( CScriptObj::r_WriteVal( pszKey, sVal, pSrc )); } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }
bool CPartyDef::r_WriteVal( LPCTSTR pszKey, CGString &sVal, CTextConsole *pSrc ) { ADDTOCALLSTACK("CPartyDef::r_WriteVal"); EXC_TRY("WriteVal"); 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(static_cast<DWORD>(pObj->GetUID())); else sVal.FormatVal(1); return true; } return pRef->r_WriteVal(pszKey, sVal, pSrc); } bool fZero = false; switch ( FindTableHeadSorted(pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys) - 1) ) { case PDC_ISSAMEPARTYOF: { pszKey += 13; GETNONWHITESPACE(pszKey); if ( pszKey[0] != '\0' ) { CGrayUID uidToCheck = static_cast<CGrayUID>(Exp_GetVal(pszKey)); CChar *pCharToCheck = uidToCheck.CharFind(); sVal.FormatVal(pCharToCheck && (pCharToCheck->m_pParty == this)); } else return false; } break; case PDC_MEMBERS: sVal.FormatVal(m_Chars.GetCharCount()); break; case PDC_SPEECHFILTER: sVal = m_pSpeechFunction.IsEmpty() ? "" : m_pSpeechFunction; break; case PDC_TAG0: fZero = true; pszKey++; case PDC_TAG: { if ( pszKey[3] != '.' ) return false; pszKey += 4; sVal = m_TagDefs.GetKeyStr(pszKey, fZero); } break; case PDC_TAGAT: { pszKey += 5; // eat the 'TAGAT' if ( *pszKey == '.' ) // do we have an argument? { SKIP_SEPARATORS(pszKey); size_t iQty = static_cast<size_t>(Exp_GetVal(pszKey)); if ( iQty >= m_TagDefs.GetCount() ) return false; // trying to get non-existant tag CVarDefCont *pTagAt = m_TagDefs.GetAt(iQty); if ( !pTagAt ) return false; // trying to get non-existant tag SKIP_SEPARATORS(pszKey); if ( !*pszKey ) { sVal.Format("%s=%s", pTagAt->GetKey(), pTagAt->GetValStr()); return true; } else if ( !strnicmp(pszKey, "KEY", 3) ) { sVal = pTagAt->GetKey(); return true; } else if ( !strnicmp(pszKey, "VAL", 3) ) { sVal = pTagAt->GetValStr(); return true; } } return false; } case PDC_TAGCOUNT: sVal.FormatVal(m_TagDefs.GetCount()); break; default: return false; } return true; EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }