bool CPartyDef::r_Verb( CScript &s, CTextConsole *pSrc ) { ADDTOCALLSTACK("CPartyDef::r_Verb"); EXC_TRY("Verb"); ASSERT(pSrc); LPCTSTR pszKey = s.GetKey(); 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); } } int iIndex = FindTableSorted(pszKey, sm_szVerbKeys, COUNTOF(sm_szVerbKeys) - 1); switch ( iIndex ) { case PDV_ADDMEMBER: case PDV_ADDMEMBERFORCED: { bool bForced = (iIndex == PDV_ADDMEMBERFORCED); CGrayUID toAdd = static_cast<CGrayUID>(s.GetArgVal()); CChar *pCharAdd = toAdd.CharFind(); CChar *pCharMaster = GetMaster().CharFind(); if ( !pCharAdd || IsInParty(pCharAdd) ) return false; if ( pCharMaster && !bForced ) pCharMaster->SetKeyNum("PARTY_LASTINVITE", (long long)toAdd); return CPartyDef::AcceptEvent(pCharAdd, GetMaster(), bForced); } break; case PDV_CLEARTAGS: { LPCTSTR pszArg = s.GetArgStr(); SKIP_SEPARATORS(pszArg); m_TagDefs.ClearKeys(pszArg); } break; case PDV_CREATE: return true; case PDV_DISBAND: return Disband(GetMaster()); case PDV_MESSAGE: break; case PDV_REMOVEMEMBER: { CGrayUID toRemove; LPCTSTR pszArg = s.GetArgStr(); if ( *pszArg == '@' ) { pszArg++; size_t nMember = Exp_GetVal(pszArg); if ( !m_Chars.IsValidIndex(nMember) ) return false; toRemove = m_Chars.GetChar(nMember); } else toRemove = static_cast<CGrayUID>(s.GetArgVal()); if ( toRemove ) return RemoveMember(toRemove, GetMaster()); return false; } break; case PDV_SETMASTER: { CGrayUID newMaster; LPCTSTR pszArg = s.GetArgStr(); if ( *pszArg == '@' ) { pszArg++; size_t nMember = Exp_GetVal(pszArg); if ( nMember == 0 || !m_Chars.IsValidIndex(nMember) ) return false; newMaster = m_Chars.GetChar(nMember); } else newMaster = static_cast<CGrayUID>(s.GetArgVal()); if ( newMaster ) return SetMaster(newMaster.CharFind()); return false; } break; case PDV_SYSMESSAGE: { CGrayUID toSysmessage; LPCTSTR pszArg = s.GetArgStr(); TCHAR *pUid = Str_GetTemp(); size_t x = 0; if ( *pszArg == '@' ) { pszArg++; if ( *pszArg != '@' ) { LPCTSTR __pszArg = pszArg; while ( *pszArg != ' ' ) { pszArg++; x++; } strcpylen(pUid, __pszArg, ++x); size_t nMember = Exp_GetVal(pUid); if ( !m_Chars.IsValidIndex(nMember) ) return false; toSysmessage = m_Chars.GetChar(nMember); } } else { LPCTSTR __pszArg = pszArg; while ( *pszArg != ' ' ) { pszArg++; x++; } strcpylen(pUid, __pszArg, ++x); toSysmessage = static_cast<CGrayUID>(Exp_GetVal(pUid)); } SKIP_SEPARATORS(pszArg); if ( toSysmessage ) { CChar *pSend = toSysmessage.CharFind(); pSend->SysMessage(pszArg); } else SysMessageAll(pszArg); } break; case PDV_TAGLIST: m_TagDefs.DumpKeys(pSrc, "TAG."); break; default: return false; } 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 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; }
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; }