int CLuaFunctionDefs::toJSON ( lua_State* luaVM ) { // Got a string argument? if ( lua_type ( luaVM, 1 ) > LUA_TNIL ) { // Read the argument CLuaArguments JSON; JSON.ReadArgument ( luaVM, 1 ); // Convert it to a JSON string std::string strJSON; if ( JSON.WriteToJSONString ( strJSON ) ) { // Return the JSON string lua_pushstring ( luaVM, strJSON.c_str () ); return 1; } } // Failed lua_pushnil ( luaVM ); return 1; }
CLuaTimer* CLuaTimerManager::AddTimer ( lua_State* luaVM ) { if ( luaVM ) { int iArgument2 = lua_type ( luaVM, 2 ); int iArgument3 = lua_type ( luaVM, 3 ); if ( lua_type ( luaVM, 1 ) && (( iArgument2 == LUA_TNUMBER || iArgument2 == LUA_TSTRING ) || ( iArgument3 == LUA_TNUMBER || iArgument3 == LUA_TSTRING ) )) { // Grab the string argument, start-time, delay and repeats unsigned long ulTimeDelay = static_cast < unsigned long > ( lua_tonumber ( luaVM, 2 ) ); unsigned int uiRepeats = static_cast < unsigned int > ( lua_tonumber ( luaVM, 3 ) ); // Check for the minimum interval if ( ulTimeDelay < LUA_TIMER_MIN_INTERVAL ) return NULL; // Grab the arguments from argument 4 and up CLuaArguments Arguments; Arguments.ReadArguments ( luaVM, 4 ); int iLuaFunction = luaM_toref ( luaVM, 1 ); if ( iLuaFunction != LUA_REFNIL ) { // Add the timer CLuaTimer* pLuaTimer = new CLuaTimer ( iLuaFunction, Arguments ); pLuaTimer->SetStartTime ( GetTime () ); pLuaTimer->SetDelay ( ulTimeDelay ); pLuaTimer->SetRepeats ( uiRepeats ); m_TimerList.push_back ( pLuaTimer ); return pLuaTimer; } } } return false; }
void CElement::ReadCustomData ( CLuaMain* pLuaMain, CEvents* pEvents ) { assert ( pLuaMain ); assert ( pEvents ); // Got an XML node? if ( m_pXMLNode ) { // Iterate the attributes of our XML node CXMLAttributes* pAttributes = &(m_pXMLNode->GetAttributes ()); unsigned int uiAttributeCount = pAttributes->Count (); for ( unsigned int uiIndex = 0; uiIndex < uiAttributeCount; uiIndex++ ) { // Grab the node (we can assume it exists here) CXMLAttribute* pAttribute = pAttributes->Get ( uiIndex ); // Make a lua argument from it and set the content CLuaArguments args; if ( !args.ReadFromJSONString ( pAttribute->GetValue ().c_str() ) ) args.PushString ( pAttribute->GetValue ().c_str () ); SetCustomData ( pAttribute->GetName ().c_str (), *args[0], pLuaMain ); } } }
bool CResource::CallExportedFunction ( const char * szFunctionName, CLuaArguments& args, CLuaArguments& returns, CResource& caller ) { list < CExportedFunction* > ::iterator iter = m_exportedFunctions.begin (); for ( ; iter != m_exportedFunctions.end (); iter++ ) { if ( strcmp ( (*iter)->GetFunctionName(), szFunctionName ) == 0 ) { if ( args.CallGlobal ( m_pLuaVM, szFunctionName, &returns ) ) { return true; } } } return false; }
int CLuaFunctionDefs::fromJSON ( lua_State* luaVM ) { SString strJSON; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strJSON ); if ( !argStream.HasErrors () ) { // Read it into lua arguments CLuaArguments Converted; if ( Converted.ReadFromJSONString ( strJSON ) ) { // Return it as data Converted.PushArguments ( luaVM ); return Converted.Count (); } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushnil ( luaVM ); return 1; }
// // Handle the changing state of collision between one colshape and one entity // void CClientColManager::HandleHitDetectionResult ( bool bHit, CClientColShape* pShape, CClientEntity* pEntity ) { if ( bHit ) { // If they havn't collided yet if ( !pEntity->CollisionExists ( pShape ) ) { // Add the collision and the collider pShape->AddCollider ( pEntity ); pEntity->AddCollision ( pShape ); // Can we call the event? if ( pShape->GetAutoCallEvent () ) { // Call the event CLuaArguments Arguments; Arguments.PushElement ( pEntity ); Arguments.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) ); pShape->CallEvent ( "onClientColShapeHit", Arguments, true ); CLuaArguments Arguments2; Arguments2.PushElement ( pShape ); Arguments2.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) ); pEntity->CallEvent ( "onClientElementColShapeHit", Arguments2, true ); } // Run whatever callback the collision item might have attached pShape->CallHitCallback ( *pEntity ); } } else { // If they collided before if ( pEntity->CollisionExists ( pShape ) ) { // Remove the collision and the collider pShape->RemoveCollider ( pEntity ); pEntity->RemoveCollision ( pShape ); // Call the event CLuaArguments Arguments; Arguments.PushElement ( pEntity ); Arguments.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) ); pShape->CallEvent ( "onClientColShapeLeave", Arguments, true ); CLuaArguments Arguments2; Arguments2.PushElement ( pShape ); Arguments2.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) ); pEntity->CallEvent ( "onClientElementColShapeLeave", Arguments2, true ); pShape->CallLeaveCallback ( *pEntity ); } } }
void CScriptDebugging::LogError ( SString strFile, int iLine, SString strMsg ) { SString strText = SString ( "ERROR: %s:%d: %s", strFile.c_str (), iLine, strMsg.c_str () ); if ( !m_bTriggeringOnDebugMessage ) { m_bTriggeringOnDebugMessage = true; // Prepare onDebugMessage CLuaArguments Arguments; Arguments.PushString ( strMsg.c_str ( ) ); Arguments.PushNumber ( 1 ); // Push the file name (if any) if ( strFile.length ( ) > 0 ) Arguments.PushString ( strFile.c_str ( ) ); else Arguments.PushNil ( ); // Push the line (if any) if ( iLine > -1 ) Arguments.PushNumber ( iLine ); else Arguments.PushNil ( ); // Call onDebugMessage g_pGame->GetMapManager ( )->GetRootElement ( )->CallEvent ( "onDebugMessage", Arguments ); m_bTriggeringOnDebugMessage = false; } // Log it to the file if enough level if ( m_uiLogFileLevel >= 1 ) { PrintLog ( strText ); } // Log to console CLogger::LogPrintf( "%s\n", strText.c_str () ); // Tell the players Broadcast ( CDebugEchoPacket ( strText, 1, 255, 255, 255 ), 1 ); }
void CScriptDebugging::LogString ( const char* szPrePend, const SLuaDebugInfo& luaDebugInfo, const char* szMessage, unsigned int uiMinimumDebugLevel, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue ) { SString strText = ComposeErrorMessage( szPrePend, luaDebugInfo, szMessage ); // Create a different message if type is "INFO" if ( uiMinimumDebugLevel > 2 ) strText = SString ( "%s%s", szPrePend, szMessage ); // Check whether onDebugMessage is currently being triggered if ( !m_bTriggeringOnDebugMessage ) { // Make sure the state of onDebugMessage being triggered can be retrieved later m_bTriggeringOnDebugMessage = true; // Prepare onDebugMessage CLuaArguments Arguments; Arguments.PushString ( szMessage ); Arguments.PushNumber ( uiMinimumDebugLevel ); // Push the file name (if any) if ( !luaDebugInfo.strFile.empty() ) Arguments.PushString ( luaDebugInfo.strFile ); else Arguments.PushNil ( ); // Push the line (if any) if ( luaDebugInfo.iLine != INVALID_LINE_NUMBER ) Arguments.PushNumber ( luaDebugInfo.iLine ); else Arguments.PushNil ( ); // Call onDebugMessage g_pGame->GetMapManager ( )->GetRootElement ( )->CallEvent ( "onDebugMessage", Arguments ); // Reset trigger state, so onDebugMessage can be called again at a later moment m_bTriggeringOnDebugMessage = false; } m_DuplicateLineFilter.AddLine( { strText, uiMinimumDebugLevel, ucRed, ucGreen, ucBlue } ); if ( g_pGame->GetConfig()->GetFilterDuplicateLogLinesEnabled() == false ) m_DuplicateLineFilter.Flush(); UpdateLogOutput(); }
void CSocket::TriggerEvent(const string eventName, const string arg1) { CLuaArguments args; args.PushString(eventName.c_str()); lua_getglobal(m_pLuaVM, "root"); CLuaArgument RootElement(m_pLuaVM, -1); args.PushUserData(RootElement.GetLightUserData()); args.PushUserData(m_pUserdata); if (arg1.length() > 0) args.PushString(arg1.c_str()); args.Call(m_pLuaVM, "triggerEvent"); }
void CScriptDebugging::LogError ( SString strFile, int iLine, SString strMsg ) { SString strText = SString ( "ERROR: %s:%d: %s", strFile.c_str (), iLine, strMsg.c_str () ); if ( !m_bTriggeringOnClientDebugMessage ) { m_bTriggeringOnClientDebugMessage = true; // Prepare onDebugMessage CLuaArguments Arguments; Arguments.PushString ( strMsg.c_str ( ) ); Arguments.PushNumber ( 1 ); // Push the file name (if any) if ( strFile.length ( ) > 0 ) Arguments.PushString ( strFile.c_str ( ) ); else Arguments.PushNil ( ); // Push the line (if any) if ( iLine > -1 ) Arguments.PushNumber ( iLine ); else Arguments.PushNil ( ); // Call onDebugMessage g_pClientGame->GetRootEntity ( )->CallEvent ( "onClientDebugMessage", Arguments, false ); m_bTriggeringOnClientDebugMessage = false; } // Log it to the file if enough level if ( m_uiLogFileLevel >= 1 ) { PrintLog ( strText ); } // Log to console g_pCore->DebugEchoColor ( strText, 255, 0, 0 ); }
void CKeyBinds::Call ( CKeyBind* pKeyBind ) { if ( pKeyBind && !pKeyBind->IsBeingDeleted () ) { switch ( pKeyBind->GetType () ) { case KEY_BIND_FUNCTION: { CKeyFunctionBind* pBind = static_cast < CKeyFunctionBind* > ( pKeyBind ); if ( pBind->luaMain && VERIFY_FUNCTION ( pBind->m_iLuaFunction ) ) { CLuaArguments Arguments; Arguments.PushElement ( m_pPlayer ); Arguments.PushString ( pBind->boundKey->szKey ); Arguments.PushString ( ( pBind->bHitState ) ? "down" : "up" ); Arguments.PushArguments ( pBind->m_Arguments ); Arguments.Call ( pBind->luaMain, pBind->m_iLuaFunction ); } break; } case KEY_BIND_CONTROL_FUNCTION: { CControlFunctionBind* pBind = static_cast < CControlFunctionBind* > ( pKeyBind ); if ( pBind->luaMain && VERIFY_FUNCTION ( pBind->m_iLuaFunction ) ) { CLuaArguments Arguments; Arguments.PushElement ( m_pPlayer ); Arguments.PushString ( pBind->boundControl->szControl ); Arguments.PushString ( ( pBind->bHitState ) ? "down" : "up" ); Arguments.PushArguments ( pBind->m_Arguments ); Arguments.Call ( pBind->luaMain, pBind->m_iLuaFunction ); } break; } default: break; } } }
void CResource::Load ( CClientEntity *pRootEntity ) { m_pRootEntity = pRootEntity; if ( m_pRootEntity ) { // Set the GUI parent to the resource root entity m_pResourceCOLRoot->SetParent ( m_pResourceEntity ); m_pResourceDFFEntity->SetParent ( m_pResourceEntity ); m_pResourceGUIEntity->SetParent ( m_pResourceEntity ); m_pResourceTXDRoot->SetParent ( m_pResourceEntity ); } CLogger::LogPrintf ( "> Starting resource '%s'", m_szResourceName ); char szBuffer [ MAX_PATH ] = { 0 }; list < CResourceConfigItem* >::iterator iterc = m_ConfigFiles.begin (); for ( ; iterc != m_ConfigFiles.end (); iterc++ ) { if ( !(*iterc)->Start() ) { CLogger::LogPrintf ( "Failed to start resource item %s in %s\n", (*iterc)->GetName(), m_szResourceName ); } } // Load the files that are queued in the list "to be loaded" list < CResourceFile* > ::iterator iter = m_ResourceFiles.begin (); for ( ; iter != m_ResourceFiles.end (); iter++ ) { CResourceFile* pResourceFile = *iter; // Only load the resource file if it is a client script if ( pResourceFile->GetResourceType () == CDownloadableResource::RESOURCE_FILE_TYPE_CLIENT_SCRIPT ) { // Load the file std::vector < char > buffer; FileLoad ( pResourceFile->GetName (), buffer ); // Check the contents if ( buffer.size () > 0 && CChecksum::GenerateChecksumFromBuffer ( &buffer.at ( 0 ), buffer.size () ).CompareWithLegacy ( pResourceFile->GetServerChecksum () ) ) { // Load the resource text m_pLuaVM->LoadScriptFromBuffer ( &buffer.at ( 0 ), buffer.size (), pResourceFile->GetName () ); } else { SString strBuffer ( "ERROR: File '%s' in resource '%s' - CRC mismatch.", pResourceFile->GetShortName (), m_szResourceName ); g_pCore->ChatEchoColor ( strBuffer, 255, 0, 0 ); } } else if ( CheckFileForCorruption ( pResourceFile->GetName () ) ) { SString strBuffer ( "WARNING: File '%s' in resource '%s' is invalid.", pResourceFile->GetShortName (), m_szResourceName ); g_pCore->DebugEchoColor ( strBuffer, 255, 0, 0 ); } } // Set active flag m_bActive = true; // Did we get a resource root entity? if ( m_pResourceEntity ) { // Call the Lua "onClientResourceStart" event CLuaArguments Arguments; Arguments.PushUserData ( this ); m_pResourceEntity->CallEvent ( "onClientResourceStart", Arguments, true ); } else assert ( 0 ); }
void CClientWebBrowser::Events_OnInputFocusChanged ( bool bGainedFocus ) { CLuaArguments Arguments; Arguments.PushBoolean ( bGainedFocus ); CallEvent ( "onClientBrowserInputFocusChanged", Arguments, false ); }
void CClientWebBrowser::Events_OnChangeCursor ( unsigned char ucCursor ) { CLuaArguments Arguments; Arguments.PushNumber ( ucCursor ); CallEvent ( "onClientBrowserCursorChange", Arguments, false ); }
void CClientWebBrowser::Events_OnTooltip ( const SString& strTooltip ) { CLuaArguments Arguments; Arguments.PushString ( strTooltip ); CallEvent ( "onClientBrowserTooltip", Arguments, false ); }
int CLuaFunctionDefs::Call ( lua_State* luaVM ) { CResource * pResource = NULL; SString strFunctionName = ""; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pResource ); argStream.ReadString ( strFunctionName ); if ( !argStream.HasErrors ( ) ) { // Grab our VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Grab this resource CResource* pThisResource = pLuaMain->GetResource (); if ( pThisResource ) { if ( pResource ) { //Get the target Lua VM lua_State* targetLuaVM = pResource->GetVM()->GetVM(); // Read out the vargs CLuaArguments args; args.ReadArguments ( luaVM, 3 ); CLuaArguments returns; LUA_CHECKSTACK ( targetLuaVM, 1 ); // Ensure some room //Lets grab the original hidden variables so we can restore them later lua_getglobal ( targetLuaVM, "sourceResource" ); CLuaArgument OldResource ( luaVM, -1 ); lua_pop( targetLuaVM, 1 ); lua_getglobal ( targetLuaVM, "sourceResourceRoot" ); CLuaArgument OldResourceRoot ( luaVM, -1 ); lua_pop( targetLuaVM, 1 ); //Set the new values for the current sourceResource, and sourceResourceRoot lua_pushresource ( targetLuaVM, pThisResource ); lua_setglobal ( targetLuaVM, "sourceResource" ); lua_pushelement ( targetLuaVM, pThisResource->GetResourceEntity() ); lua_setglobal ( targetLuaVM, "sourceResourceRoot" ); // Call the exported function with the given name and the args if ( pResource->CallExportedFunction ( strFunctionName, args, returns, *pThisResource ) ) { // Push return arguments returns.PushArguments ( luaVM ); //Restore the old variables OldResource.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResource" ); OldResourceRoot.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResourceRoot" ); return returns.Count (); } else { //Restore the old variables OldResource.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResource" ); OldResourceRoot.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResourceRoot" ); m_pScriptDebugging->LogError ( luaVM, "call: failed to call '%s:%s'", pResource->GetName (), *strFunctionName ); } } else { m_pScriptDebugging->LogBadType ( luaVM ); } } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
void CRPCFunctions::CursorEvent ( NetBitStreamInterface & bitStream ) { SMouseButtonSync button; unsigned char ucButton; CVector2D vecCursorPosition; unsigned short usX; unsigned short usY; SPositionSync position ( false ); CVector vecPosition; bool bHasCollisionElement; ElementID elementID; if ( bitStream.Read ( &button ) && bitStream.ReadCompressed ( usX ) && bitStream.ReadCompressed ( usY ) && bitStream.Read ( &position ) && bitStream.ReadBit ( bHasCollisionElement ) && ( !bHasCollisionElement || bitStream.ReadCompressed ( elementID ) ) ) { ucButton = button.data.ucButton; vecCursorPosition.fX = static_cast < float > ( usX ); vecCursorPosition.fY = static_cast < float > ( usY ); vecPosition = position.data.vecPosition; if ( !bHasCollisionElement ) elementID = INVALID_ELEMENT_ID; } else return; if ( m_pSourcePlayer->IsJoined () ) { // Get the button and state const char* szButton = NULL; const char* szState = NULL; switch ( ucButton ) { case 0: szButton = "left"; szState = "down"; break; case 1: szButton = "left"; szState = "up"; break; case 2: szButton = "middle"; szState = "down"; break; case 3: szButton = "middle"; szState = "up"; break; case 4: szButton = "right"; szState = "down"; break; case 5: szButton = "right"; szState = "up"; break; } if ( szButton && szState ) { CElement* pElement = CElementIDs::GetElement ( elementID ); if ( pElement ) { // Call the onElementClicked event CLuaArguments Arguments; Arguments.PushString ( szButton ); Arguments.PushString ( szState ); Arguments.PushElement ( m_pSourcePlayer ); Arguments.PushNumber ( vecPosition.fX ); Arguments.PushNumber ( vecPosition.fY ); Arguments.PushNumber ( vecPosition.fZ ); pElement->CallEvent ( "onElementClicked", Arguments ); } // Call the onPlayerClick event CLuaArguments Arguments; Arguments.PushString ( szButton ); Arguments.PushString ( szState ); if ( pElement ) Arguments.PushElement ( pElement ); else Arguments.PushNil (); Arguments.PushNumber ( vecPosition.fX ); Arguments.PushNumber ( vecPosition.fY ); Arguments.PushNumber ( vecPosition.fZ ); Arguments.PushNumber ( vecCursorPosition.fX ); Arguments.PushNumber ( vecCursorPosition.fY ); m_pSourcePlayer->CallEvent ( "onPlayerClick", Arguments ); // TODO: iterate server-side element managers for the click events, eg: colshapes } } }
//////////////////////////////////////////////////////////// // // CClientSound::Process3D // // Update position and velocity and pass on the BASS for processing. // m_pAudio->DoPulse needs to be called for non-3D sounds also. // //////////////////////////////////////////////////////////// void CClientSound::Process3D ( const CVector& vecPlayerPosition, const CVector& vecCameraPosition, const CVector& vecLookAt ) { // Update 3D things if required if ( m_b3D ) { // Update our position and velocity if we're attached CClientEntity* pAttachedToEntity = GetAttachedTo (); if ( pAttachedToEntity ) { GetPosition( m_vecPosition ); DoAttaching (); CVector vecVelocity; if ( CStaticFunctionDefinitions::GetElementVelocity ( *pAttachedToEntity, vecVelocity ) ) SetVelocity ( vecVelocity ); // Update our spatial data position UpdateSpatialData (); } } // If the sound isn't active, we don't need to process it // Moved after 3D updating as the streamer didn't know the position changed if a sound isn't streamed in when attached. if ( !m_pAudio ) return; m_pAudio->DoPulse ( vecPlayerPosition, vecCameraPosition, vecLookAt ); // Trigger script events for things SSoundEventInfo eventInfo; while ( m_pAudio->GetQueuedEvent ( eventInfo ) ) { if ( eventInfo.type == SOUND_EVENT_FINISHED_DOWNLOAD ) { CLuaArguments Arguments; Arguments.PushNumber ( eventInfo.dNumber ); CallEvent ( "onClientSoundFinishedDownload", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundFinishedDownload %f", eventInfo.dNumber ) ); } else if ( eventInfo.type == SOUND_EVENT_CHANGED_META ) { CLuaArguments Arguments; Arguments.PushString ( eventInfo.strString ); CallEvent ( "onClientSoundChangedMeta", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundChangedMeta %s", *eventInfo.strString ) ); } else if ( eventInfo.type == SOUND_EVENT_STREAM_RESULT ) { // Call onClientSoundStream LUA event CLuaArguments Arguments; Arguments.PushBoolean ( eventInfo.bBool ); Arguments.PushNumber ( eventInfo.dNumber ); if ( !eventInfo.strString.empty () ) Arguments.PushString ( eventInfo.strString ); CallEvent ( "onClientSoundStream", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundStream %d %f %s", eventInfo.bBool, eventInfo.dNumber, *eventInfo.strString ) ); } else if ( eventInfo.type == SOUND_EVENT_BEAT ) { CLuaArguments Arguments; Arguments.PushNumber ( eventInfo.dNumber ); CallEvent ( "onClientSoundBeat", Arguments, true ); } } }
bool CConsole::HandleInput ( const char* szCommand, CClient* pClient, CClient* pEchoClient ) { // Copy it char szCommandBuffer [256]; szCommandBuffer [255] = 0; strncpy ( szCommandBuffer, szCommand, 255 ); stripControlCodes ( szCommandBuffer ); // Split it into two parts: Key and argument char* szKey = strtok ( szCommandBuffer, " " ); char* szArguments = strtok ( NULL, "\0" ); // Does the key exist? if ( szKey && szKey [0] != 0 ) { CConsoleCommand* pCommand = GetCommand ( szKey ); if ( pCommand ) { // Can this user use this command? if ( m_pACLManager->CanObjectUseRight ( pClient->GetAccount ()->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_USER, szKey, CAccessControlListRight::RIGHT_TYPE_COMMAND, !pCommand->IsRestricted () ) ) { return (*pCommand)( this, szArguments, pClient, pEchoClient ); } // Not enough access, tell the console CLogger::LogPrintf ( "DENIED: Denied '%s' access to command '%s'\n", pClient->GetNick (), szKey ); // Tell the client char szBuffer [128]; _snprintf ( szBuffer, sizeof(szBuffer), "ACL: Access denied for '%s'", szKey ); szBuffer[sizeof(szBuffer)-1] = '\0'; pClient->SendEcho ( szBuffer ); return false; } // Let the script handle it int iClientType = pClient->GetClientType (); switch ( iClientType ) { case CClient::CLIENT_PLAYER: { // See if any registered command can process it CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); m_pRegisteredCommands->ProcessCommand ( szKey, szArguments, pClient ); // HACK: if the client gets destroyed before here, dont continue if ( m_pPlayerManager->Exists ( pPlayer ) ) { // Call the console event CLuaArguments Arguments; Arguments.PushString ( szCommand ); pPlayer->CallEvent ( "onConsole", Arguments ); } break; } case CClient::CLIENT_CONSOLE: { // See if any registered command can process it CConsoleClient* pConsole = static_cast < CConsoleClient* > ( pClient ); m_pRegisteredCommands->ProcessCommand ( szKey, szArguments, pClient ); // Call the console event CLuaArguments Arguments; Arguments.PushString ( szCommand ); pConsole->CallEvent ( "onConsole", Arguments ); break; } default: break; } } // Doesn't exist return false; }
bool COMMAND_Executed(const char* szCommand, const char* szArguments, bool bHandleRemotely, bool bHandled, bool bIsScriptedBind) { // Has the core already handled this command? if (!bHandled) { const char* szCommandBufferPointer = szCommand; if (!bHandleRemotely) { // Is the command "say" and the arguments start with '/' ? (command comes from the chatbox) if (stricmp(szCommand, "chatboxsay") == 0) { szCommandBufferPointer = "say"; } } // Toss them together so we can send it to the server SString strClumpedCommand; if (szArguments && szArguments[0]) strClumpedCommand.Format("%s %s", szCommandBufferPointer, szArguments); else strClumpedCommand = szCommandBufferPointer; // Convert to Unicode, and clamp it to a maximum command length std::wstring strClumpedCommandUTF = MbUTF8ToUTF16(strClumpedCommand.c_str()); strClumpedCommandUTF = strClumpedCommandUTF.substr(0, MAX_COMMAND_LENGTH); strClumpedCommand = UTF16ToMbUTF8(strClumpedCommandUTF); g_pClientGame->GetRegisteredCommands()->ProcessCommand(szCommandBufferPointer, szArguments); // Call the onClientConsole event auto pLocalPlayer = g_pClientGame->GetLocalPlayer(); if (pLocalPlayer) { CLuaArguments Arguments; // Censor input for /login command if (!stricmp(szCommandBufferPointer, "login")) { Arguments.PushString(SString("%s ***", szCommandBufferPointer)); } else { Arguments.PushString(strClumpedCommand); } pLocalPlayer->CallEvent("onClientConsole", Arguments, true); } // Write the chatlength and the content NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream(); if (!pBitStream) return false; // Write it to the bitstream pBitStream->Write(strClumpedCommand.c_str(), static_cast<int>(strlen(strClumpedCommand.c_str()))); // Send the packet to the server and free it g_pNet->SendPacket(PACKET_ID_COMMAND, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_CHAT); g_pNet->DeallocateNetBitStream(pBitStream); return true; } else { // Call our comand-handlers for core-executed commands too g_pClientGame->GetRegisteredCommands()->ProcessCommand(szCommand, szArguments); } return false; }
// Set ( resource requesting the query, setting name, content ) bool CSettings::Set(const char *szLocalResource, const char *szSetting, const char *szContent) { CXMLNode * pNode; CResource * pResource; CXMLAttributes *pAttributes; char szBuffer[MAX_SETTINGS_LENGTH] = {0}; char szQueryResource[MAX_RESOURCE_LENGTH] = {0}; SettingStatus eStatus; bool bDeleteNode, bExists; SString strOldValue; // Check for empty strings if (strlen(szSetting) < 1) return false; // Get the actual resource name from the specified setting, and get the resource class if (!GetResourceName(szSetting, szQueryResource, MAX_RESOURCE_LENGTH - 1)) { // No name was specified, so use the local resource pResource = m_pResourceManager->GetResource(szLocalResource); } else pResource = m_pResourceManager->GetResource(szQueryResource); // If we have a valid resource if (pResource) { CXMLNode *pSource = pResource->GetSettingsNode(); // Check whether the setting exists in the settings registry pNode = Get(m_pNodeGlobalSettings, NULL, "", szLocalResource, szSetting, bDeleteNode, eStatus); bExists = true; // Default value // Try to get the value for the appropriate setting from the resource's meta XML file if (eStatus == NotFound && pSource) { pNode = Get(pSource, NULL, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eStatus); bExists = false; // There's no node in the settings registry, so we create one } // See if we have access if (eStatus != NoAccess) { // See if we have a prefix bool bPrefix = HasPrefix(szSetting[0]); // If no resource name was specified, use the local resource name if (!HasResourceName(szSetting)) { // If we have a prefix, move it from szSetting and put it at the beginning if (bPrefix) snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%c%s.%s", szSetting[0], szLocalResource, szSetting + 1); else snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%s.%s", szLocalResource, szSetting); } else { // If we have a prefix, move it from szSetting and put it at the beginning if (bPrefix) snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%c%s", szSetting[0], szSetting + 1); else strncpy(szBuffer, szSetting, MAX_SETTINGS_LENGTH - 1); } if (!bExists || !pNode) { // No existing settings registry entry, so create a new setting CreateSetting(m_pNodeGlobalSettings, szBuffer, szContent); } else { // Existing settings registry entry // Get the attributes pAttributes = &(pNode->GetAttributes()); // Abort if this value isnt public (but protected or private), and if the local resource // (doing the query) doesn't equal the setting's resource name if (GetAccessType(pAttributes->Find("name")->GetValue()[0]) != CSettings::Public && stricmp(pResource->GetName().c_str(), szLocalResource) != 0) return false; // Get the node's current value strOldValue = pAttributes->Find("value")->GetValue(); // Set the node's value pAttributes->Find("value")->SetValue(szContent); // If a prefix was given, set the node's name (to override any access operators) if (bPrefix) pAttributes->Find("name")->SetValue(szBuffer); } // Trigger onSettingChange CLuaArguments Arguments; Arguments.PushString(szSetting); if (strOldValue.length() > 0) Arguments.PushString(strOldValue.c_str()); else Arguments.PushNil(); Arguments.PushString(szContent); g_pGame->GetMapManager()->GetRootElement()->CallEvent("onSettingChange", Arguments); // Save the XML file if (m_pFile->Write()) return true; CLogger::ErrorPrintf("Error saving '%s'\n", FILENAME_SETTINGS); } } return false; }
bool CPlayerPuresyncPacket::Read ( NetBitStreamInterface& BitStream ) { if ( m_pSourceElement ) { CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement ); // Read out the time context unsigned char ucTimeContext = 0; if ( !BitStream.Read ( ucTimeContext ) ) return false; // Only read this packet if it matches the current time context that // player is in. if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) ) { return false; } // Read out keys CControllerState ControllerState; ReadFullKeysync ( ControllerState, BitStream ); pSourcePlayer->GetPad ()->NewControllerState ( ControllerState ); // Read the flags SPlayerPuresyncFlags flags; if ( !BitStream.Read ( &flags ) ) return false; pSourcePlayer->SetInWater ( flags.data.bIsInWater ); pSourcePlayer->SetOnGround ( flags.data.bIsOnGround ); pSourcePlayer->SetHasJetPack ( flags.data.bHasJetPack ); pSourcePlayer->SetDucked ( flags.data.bIsDucked ); pSourcePlayer->SetWearingGoggles ( flags.data.bWearsGoogles ); pSourcePlayer->SetChoking ( flags.data.bIsChoking ); pSourcePlayer->SetAkimboArmUp ( flags.data.bAkimboTargetUp ); pSourcePlayer->SetOnFire ( flags.data.bIsOnFire ); pSourcePlayer->SetStealthAiming ( flags.data.bStealthAiming ); // Contact element CElement* pContactElement = NULL; if ( flags.data.bHasContact ) { ElementID Temp; if ( !BitStream.ReadCompressed ( Temp ) ) return false; pContactElement = CElementIDs::GetElement ( Temp ); } CElement * pPreviousContactElement = pSourcePlayer->GetContactElement (); pSourcePlayer->SetContactElement ( pContactElement ); if ( pPreviousContactElement != pContactElement ) { // Call our onPlayerContact event CLuaArguments Arguments; if ( pPreviousContactElement ) Arguments.PushElement ( pPreviousContactElement ); else Arguments.PushNil (); if ( pContactElement ) Arguments.PushElement ( pContactElement ); else Arguments.PushNil (); pSourcePlayer->CallEvent ( "onPlayerContact", Arguments ); } // Player position SPositionSync position ( false ); if ( !BitStream.Read ( &position ) ) return false; if ( pContactElement ) { pSourcePlayer->SetContactPosition ( position.data.vecPosition ); // Get the true position CVector vecTempPos = pContactElement->GetPosition (); position.data.vecPosition += vecTempPos; } pSourcePlayer->SetPosition ( position.data.vecPosition ); // Player rotation SPedRotationSync rotation; if ( !BitStream.Read ( &rotation ) ) return false; pSourcePlayer->SetRotation ( rotation.data.fRotation ); // Move speed vector if ( flags.data.bSyncingVelocity ) { SVelocitySync velocity; if ( !BitStream.Read ( &velocity ) ) return false; pSourcePlayer->SetVelocity ( velocity.data.vecVelocity ); } // Health ( stored with damage ) SPlayerHealthSync health; if ( !BitStream.Read ( &health ) ) return false; float fHealth = health.data.fValue; // Armor SPlayerArmorSync armor; if ( !BitStream.Read ( &armor ) ) return false; float fArmor = armor.data.fValue; float fOldArmor = pSourcePlayer->GetArmor (); float fArmorLoss = fOldArmor - fArmor; pSourcePlayer->SetArmor ( fArmor ); // Read out and set the camera rotation float fCameraRotation; if ( !BitStream.Read ( fCameraRotation ) ) return false; pSourcePlayer->SetCameraRotation ( fCameraRotation ); if ( flags.data.bHasAWeapon ) { if ( BitStream.Version () >= 0x0d ) { // Check client has the weapon we think he has unsigned char ucWeaponType; if ( !BitStream.Read ( ucWeaponType ) ) return false; if ( pSourcePlayer->GetWeaponType () != ucWeaponType ) return false; } // Current weapon slot SWeaponSlotSync slot; if ( !BitStream.Read ( &slot ) ) return false; unsigned int uiSlot = slot.data.uiSlot; pSourcePlayer->SetWeaponSlot ( uiSlot ); if ( CWeaponNames::DoesSlotHaveAmmo ( uiSlot ) ) { // Read out the ammo states SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), true, true ); if ( !BitStream.Read ( &ammo ) ) return false; pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip ); pSourcePlayer->SetWeaponTotalAmmo ( ammo.data.usTotalAmmo ); // Read out the aim data SWeaponAimSync sync ( pSourcePlayer->GetWeaponRange (), ( ControllerState.RightShoulder1 || ControllerState.ButtonCircle ) ); if ( !BitStream.Read ( &sync ) ) return false; // Set the arm directions and whether or not arms are up pSourcePlayer->SetAimDirection ( sync.data.fArm ); // Read the aim data only if he's shooting or aiming if ( sync.isFull() ) { pSourcePlayer->SetSniperSourceVector ( sync.data.vecOrigin ); pSourcePlayer->SetTargettingVector ( sync.data.vecTarget ); } } else { pSourcePlayer->SetWeaponAmmoInClip ( 1 ); pSourcePlayer->SetWeaponTotalAmmo ( 1 ); } } else { pSourcePlayer->SetWeaponSlot ( 0 ); pSourcePlayer->SetWeaponAmmoInClip ( 1 ); pSourcePlayer->SetWeaponTotalAmmo ( 1 ); } // Read out damage info if changed if ( BitStream.ReadBit () == true ) { ElementID DamagerID; if ( !BitStream.ReadCompressed ( DamagerID ) ) return false; SWeaponTypeSync weaponType; if ( !BitStream.Read ( &weaponType ) ) return false; SBodypartSync bodyPart; if ( !BitStream.Read ( &bodyPart ) ) return false; pSourcePlayer->SetDamageInfo ( DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart ); } // If we know the player's dead, make sure the health we send on is 0 if ( pSourcePlayer->IsDead () ) fHealth = 0.0f; float fOldHealth = pSourcePlayer->GetHealth (); float fHealthLoss = fOldHealth - fHealth; pSourcePlayer->SetHealth ( fHealth ); // Less than last packet's frame? if ( fHealthLoss > 0 || fArmorLoss > 0 ) { float fDamage = 0.0f; if ( fHealthLoss > 0 ) fDamage += fHealthLoss; if ( fArmorLoss > 0 ) fDamage += fArmorLoss; // Call the onPlayerDamage event CLuaArguments Arguments; CElement* pKillerElement = CElementIDs::GetElement ( pSourcePlayer->GetPlayerAttacker () ); if ( pKillerElement ) Arguments.PushElement ( pKillerElement ); else Arguments.PushNil (); Arguments.PushNumber ( pSourcePlayer->GetAttackWeapon () ); Arguments.PushNumber ( pSourcePlayer->GetAttackBodyPart () ); Arguments.PushNumber ( fDamage ); pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments ); } // Success return true; } return false; }
void CScriptDebugging::LogString ( const char* szPrePend, lua_State * luaVM, const char* szMessage, unsigned int uiMinimumDebugLevel, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue ) { SString strText; lua_Debug debugInfo; // Initialize values for onDebugMessage SString strMsg = szMessage; SString strFile = ""; int iLine = -1; // Get a VM from somewhere if ( !luaVM && !m_LuaMainStack.empty () ) luaVM = m_LuaMainStack.back ()->GetVM (); for ( int level = 1; level < 3; level++ ) { if ( luaVM && lua_getstack ( luaVM, level, &debugInfo ) ) { lua_getinfo ( luaVM, "nlS", &debugInfo ); // Make sure this function isn't defined in a string (eg: from runcode) if ( debugInfo.source[0] == '@' ) { // Get and store the location of the debug message strFile = debugInfo.source + 1; iLine = debugInfo.currentline; // Populate a message to print/send (unless "info" type) if ( uiMinimumDebugLevel < 3 ) strText = SString ( "%s%s:%d: %s", szPrePend, strFile.c_str (), debugInfo.currentline, szMessage ); // if the file isn't empty, stop trying any other levels break; } else { strFile = debugInfo.short_src; if ( uiMinimumDebugLevel < 3 ) strText = SString ( "%s%s %s", szPrePend, szMessage, strFile.c_str () ); if ( strFile != "[string \"?\"]" ) // if the file isn't empty, stop trying any other levels break; } } else { strText = SString ( "%s%s%s", szPrePend, m_strLineAndFile.c_str(), szMessage ); // no point in trying other levels break; } } // Create a different message if type is "INFO" if ( uiMinimumDebugLevel > 2 ) strText = SString ( "%s%s", szPrePend, szMessage ); // Check whether onDebugMessage is currently being triggered if ( !m_bTriggeringOnDebugMessage ) { // Make sure the state of onDebugMessage being triggered can be retrieved later m_bTriggeringOnDebugMessage = true; // Prepare onDebugMessage CLuaArguments Arguments; Arguments.PushString ( strMsg.c_str ( ) ); Arguments.PushNumber ( uiMinimumDebugLevel ); // Push the file name (if any) if ( strFile.length ( ) > 0 ) Arguments.PushString ( strFile.c_str ( ) ); else Arguments.PushNil ( ); // Push the line (if any) if ( iLine > -1 ) Arguments.PushNumber ( iLine ); else Arguments.PushNil ( ); // Call onDebugMessage g_pGame->GetMapManager ( )->GetRootElement ( )->CallEvent ( "onDebugMessage", Arguments ); // Reset trigger state, so onDebugMessage can be called again at a later moment m_bTriggeringOnDebugMessage = false; } // Log it to the file if enough level if ( m_uiLogFileLevel >= uiMinimumDebugLevel ) { PrintLog ( strText ); } // Log to console CLogger::LogPrintf( "%s\n", strText.c_str () ); // Not sure what this is for, seems pretty useless if ( m_uiHtmlLogLevel >= uiMinimumDebugLevel ) { if ( luaVM ) { CLuaMain* pLuaMain = g_pGame->GetLuaManager()->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { CResourceFile * file = pLuaMain->GetResourceFile(); if ( file && file->GetType() == CResourceHTMLItem::RESOURCE_FILE_TYPE_HTML ) { CResourceHTMLItem * html = (CResourceHTMLItem *)file; html->AppendToPageBuffer ( strText ); html->AppendToPageBuffer ( "<br/>" ); } } } } // Tell the players Broadcast ( CDebugEchoPacket ( strText, uiMinimumDebugLevel, ucRed, ucGreen, ucBlue ), uiMinimumDebugLevel ); }
void CRemoteCall::DownloadFinishedCallback(const SHttpDownloadResult& result) { CRemoteCall* pCall = (CRemoteCall*)result.pObj; if (!g_pClientGame->GetRemoteCalls()->CallExists(pCall)) return; CLuaArguments arguments; if (pCall->IsLegacy()) { if (result.bSuccess) { if (pCall->IsFetch()) { arguments.PushString(std::string(result.pData, result.dataSize)); arguments.PushNumber(0); } else arguments.ReadFromJSONString(result.pData); } else { arguments.PushString("ERROR"); arguments.PushNumber(result.iErrorCode); } } else { // Append response body arguments.PushString(std::string(result.pData, result.dataSize)); // Append info table CLuaArguments info; info.PushString("success"); info.PushBoolean(result.iErrorCode >= 200 && result.iErrorCode <= 299); info.PushString("statusCode"); info.PushNumber(result.iErrorCode); // Headers as a subtable CLuaArguments headers; for (auto iter : result.headers ) { headers.PushString(iter.first); headers.PushString(iter.second); } info.PushString("headers"); info.PushTable(&headers); arguments.PushTable(&info); } // Append stored arguments if (pCall->IsFetch()) for (uint i = 0; i < pCall->GetFetchArguments().Count(); i++ ) arguments.PushArgument(*(pCall->GetFetchArguments()[i])); arguments.Call(pCall->m_VM, pCall->m_iFunction); g_pClientGame->GetRemoteCalls()->Remove(pCall); }
bool CRemoteCall::ProgressCallback(double sizeJustDownloaded, double totalDownloaded, char * data, size_t dataLength, void * obj, bool complete, int error) { //printf("Progress: %s\n", data); if ( complete ) { CRemoteCall * call = (CRemoteCall*)obj; if ( g_pGame->GetRemoteCalls()->CallExists(call) ) { //printf("RECIEVED: %s\n", data); CLuaArguments arguments; if ( call->IsFetch () ) { arguments.PushString ( std::string ( data, dataLength ) ); arguments.PushNumber ( 0 ); for ( uint i = 0 ; i < call->GetFetchArguments ().Count () ; i++ ) arguments.PushArgument ( *( call->GetFetchArguments ()[i] ) ); } else arguments.ReadFromJSONString ( data ); arguments.Call ( call->m_VM, call->m_iFunction); g_pGame->GetRemoteCalls()->Remove(call); // delete ourselves return true; } } else if ( error ) { CRemoteCall * call = (CRemoteCall*)obj; if ( g_pGame->GetRemoteCalls()->CallExists(call) ) { CLuaArguments arguments; arguments.PushString("ERROR"); arguments.PushNumber(error); if ( call->IsFetch () ) for ( uint i = 0 ; i < call->GetFetchArguments ().Count () ; i++ ) arguments.PushArgument ( *( call->GetFetchArguments ()[i] ) ); arguments.Call ( call->m_VM, call->m_iFunction); g_pGame->GetRemoteCalls()->Remove(call); // delete ourselves return true; } } return false; // Possible problem }
bool CAccountManager::LogIn ( CClient* pClient, CClient* pEchoClient, const char* szAccountName, const char* szPassword ) { // Is he already logged in? if ( pClient->IsRegistered () ) { if ( pEchoClient ) pEchoClient->SendEcho ( "login: You are already logged in" ); return false; } if ( pClient->GetClientType () != CClient::CLIENT_PLAYER ) { if ( pEchoClient ) pEchoClient->SendEcho ( "login: Only players can log in" ); return false; } // Get the players details CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); SString strPlayerName = pPlayer->GetNick (); SString strPlayerIP = pPlayer->GetSourceIP (); SString strPlayerSerial = pPlayer->GetSerial (); if ( m_AccountProtect.IsFlooding ( strPlayerIP.c_str () ) ) { if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account locked", szAccountName ).c_str() ); CLogger::AuthPrintf ( "LOGIN: Ignoring %s trying to log in as '%s' (IP: %s Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () ); return false; } // Grab the account on his nick if any CAccount* pAccount = g_pGame->GetAccountManager ()->Get ( szAccountName ); if ( !pAccount ) { if ( pEchoClient ) pEchoClient->SendEcho( SString( "login: No known account for '%s'", szAccountName ).c_str() ); CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' (Unknown account) (IP: %s Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () ); return false; } if ( pAccount->GetClient () ) { if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account for '%s' is already in use", szAccountName ).c_str() ); return false; } if ( !IsValidPassword( szPassword ) || !pAccount->IsPassword ( szPassword ) ) { if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Invalid password for account '%s'", szAccountName ).c_str() ); CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' with an invalid password (IP: %s Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () ); m_AccountProtect.AddConnect ( strPlayerIP.c_str () ); return false; } // Check serial authorization if ( IsAuthorizedSerialRequired( pAccount ) ) { pAccount->AddSerialForAuthorization( strPlayerSerial, strPlayerIP ); if ( !pAccount->IsSerialAuthorized( strPlayerSerial ) ) { if ( pEchoClient ) pEchoClient->SendEcho( SString( "login: Serial pending authorization for account '%s' - See https:""//mtasa.com/authserial", szAccountName ) ); CLogger::AuthPrintf( "LOGIN: %s tried to log in as '%s' with an unauthorized serial (IP: %s Serial: %s)\n", *strPlayerName, szAccountName, *strPlayerIP, *strPlayerSerial ); CLogger::AuthPrintf( "LOGIN: See https:""//mtasa.com/authserial\n" ); return false; } } // Log him in CAccount* pCurrentAccount = pClient->GetAccount (); pClient->SetAccount ( pAccount ); pAccount->SetClient ( pClient ); // Call the onPlayerLogin script event CLuaArguments Arguments; Arguments.PushAccount ( pCurrentAccount ); Arguments.PushAccount ( pAccount ); Arguments.PushBoolean ( false ); // was bAutoLogin if ( !pPlayer->CallEvent ( "onPlayerLogin", Arguments ) ) { // DENIED! pClient->SetAccount ( pCurrentAccount ); pAccount->SetClient ( NULL ); return false; } // Success is here pAccount->OnLoginSuccess ( strPlayerSerial, strPlayerIP ); SString strGroupList = SString::Join ( ", ", g_pGame->GetACLManager ()->GetObjectGroupNames ( pAccount->GetName (), CAccessControlListGroupObject::OBJECT_TYPE_USER ) ); CLogger::AuthPrintf ( "LOGIN: (%s) %s successfully logged in as '%s' (IP: %s Serial: %s)\n", strGroupList.c_str (), pClient->GetNick (), pAccount->GetName ().c_str (), strPlayerIP.c_str (), strPlayerSerial.c_str () ); // Tell the player if ( pEchoClient ) { pEchoClient->SendEcho ( "login: You successfully logged in" ); } // Update who was info if ( pClient->GetClientType () == CClient::CLIENT_PLAYER ) g_pGame->GetConsole ()->GetWhoWas ()->OnPlayerLogin ( static_cast < CPlayer* > ( pClient ) ); // Delete the old account if it was a guest account if ( !pCurrentAccount->IsRegistered () ) delete pCurrentAccount; return true; }
int CLuaFunctionDefs::Get ( lua_State* luaVM ) { CResource* pResource = m_pLuaManager->GetVirtualMachine ( luaVM )->GetResource (); SString strSetting; CLuaArguments Args; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strSetting ); if ( !argStream.HasErrors () ) { unsigned int uiIndex = 0; bool bDeleteNode; // Extract attribute name if setting to be gotten has three parts i.e. resname.settingname.attributename SString strAttribute = "value"; vector < SString > Result; strSetting.Split ( ".", Result ); if ( Result.size () == 3 && Result[2].length () ) { strAttribute = Result[2]; } // Get the setting CXMLNode *pSubNode, *pNode = g_pGame->GetSettings ()->Get ( pResource->GetName ().c_str (), strSetting.c_str (), bDeleteNode ); // Only proceed if we have a valid node if ( pNode ) { // Argument count unsigned int uiArgCount = 1; // See if we need to return a table with single or multiple entries if ( pNode->GetSubNodeCount () == 0 ) { // See if required attribute exists CXMLAttribute *pAttribute = pNode->GetAttributes ().Find ( strAttribute.c_str () ); if ( !pAttribute ) { if ( bDeleteNode ) delete pNode; lua_pushboolean ( luaVM, false ); return 1; } // We only have a single entry for a specific setting, so output a string const std::string& strDataValue = pAttribute->GetValue (); if ( !Args.ReadFromJSONString ( strDataValue.c_str () ) ) { // No valid JSON? Parse as plain text Args.PushString ( strDataValue ); } Args.PushArguments ( luaVM ); uiArgCount = Args.Count (); /* Don't output a table because although it is more consistent with the multiple values output below, ** due to lua's implementation of associative arrays (assuming we use the "setting-name", "value" key-value pairs) ** it would require the scripter to walk through an array that only has a single entry which is a Bad Thing, performance wise. ** PUSH_SETTING ( pNode ); Args.PushAsTable ( luaVM ); **/ } else { // We need to return multiply entries, so push all subnodes while ( ( pSubNode = pNode->FindSubNode ( "setting", uiIndex++ ) ) ) { CXMLAttributes& attributes = pSubNode->GetAttributes (); Args.PushString ( attributes.Find ( "name" )->GetValue () ); const std::string& strDataValue = attributes.Find ( "value" )->GetValue (); if ( !Args.ReadFromJSONString ( strDataValue.c_str () ) ) { Args.PushString ( strDataValue ); } } // Push a table and return Args.PushAsTable ( luaVM ); } // Check if we have to delete the node if ( bDeleteNode ) delete pNode; return uiArgCount; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
bool CVehiclePuresyncPacket::Read ( NetBitStreamInterface& BitStream ) { // Got a player to read? if ( m_pSourceElement ) { CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement ); // Player is in a vehicle? CVehicle* pVehicle = pSourcePlayer->GetOccupiedVehicle (); if ( pVehicle ) { // Read out the time context unsigned char ucTimeContext = 0; if ( !BitStream.Read ( ucTimeContext ) ) return false; // Only read this packet if it matches the current time context that // player is in. if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) ) { return false; } // Read out the keysync data CControllerState ControllerState; if ( !ReadFullKeysync ( ControllerState, BitStream ) ) return false; // Read out its position SPositionSync position ( false ); if ( !BitStream.Read ( &position ) ) return false; pSourcePlayer->SetPosition ( position.data.vecPosition ); // Jax: don't allow any outdated packets through unsigned char ucSeat; if ( !BitStream.Read ( ucSeat ) ) return false; if ( ucSeat != pSourcePlayer->GetOccupiedVehicleSeat () ) { // Mis-matching seats can happen when we warp into a different one, // which will screw up the whole packet return false; } // Read out the vehicle matrix only if he's the driver unsigned int uiSeat = pSourcePlayer->GetOccupiedVehicleSeat (); if ( uiSeat == 0 ) { // Read out the vehicle rotation in degrees SRotationDegreesSync rotation; if( !BitStream.Read ( &rotation ) ) return false; // Set it pVehicle->SetPosition ( position.data.vecPosition ); pVehicle->SetRotationDegrees ( rotation.data.vecRotation ); // Move speed vector SVelocitySync velocity; if ( !BitStream.Read ( &velocity ) ) return false; pVehicle->SetVelocity ( velocity.data.vecVelocity ); pSourcePlayer->SetVelocity ( velocity.data.vecVelocity ); // Turn speed vector SVelocitySync turnSpeed; if ( !BitStream.Read ( &turnSpeed ) ) return false; pVehicle->SetTurnSpeed ( turnSpeed.data.vecVelocity ); // Health SVehicleHealthSync health; if ( !BitStream.Read ( &health ) ) return false; float fPreviousHealth = pVehicle->GetHealth (); float fHealth = health.data.fValue; // Less than last time? if ( fHealth < fPreviousHealth ) { // Grab the delta health float fDeltaHealth = fPreviousHealth - fHealth; if ( fDeltaHealth > 0.0f ) { // Call the onVehicleDamage event CLuaArguments Arguments; Arguments.PushNumber ( fDeltaHealth ); pVehicle->CallEvent ( "onVehicleDamage", Arguments ); } } pVehicle->SetHealth ( fHealth ); // Trailer chain CVehicle* pTowedByVehicle = pVehicle; CVehicle* pTrailer = NULL; ElementID TrailerID; bool bHasTrailer; if ( !BitStream.ReadBit ( bHasTrailer ) ) return false; while ( bHasTrailer ) { BitStream.ReadCompressed ( TrailerID ); CElement* pElement = CElementIDs::GetElement ( TrailerID ); if ( pElement ) pTrailer = static_cast < CVehicle* > ( pElement ); // Read out the trailer position and rotation SPositionSync trailerPosition ( false ); if ( !BitStream.Read ( &trailerPosition ) ) return false; SRotationDegreesSync trailerRotation; if ( !BitStream.Read ( &trailerRotation ) ) return false; // If we found the trailer if ( pTrailer ) { // Set its position and rotation pTrailer->SetPosition ( trailerPosition.data.vecPosition ); pTrailer->SetRotationDegrees ( trailerRotation.data.vecRotation ); // Is this a new trailer, attached? CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle (); if ( pCurrentTrailer != pTrailer ) { // If theres a trailer already attached if ( pCurrentTrailer ) { pTowedByVehicle->SetTowedVehicle ( NULL ); pCurrentTrailer->SetTowedByVehicle ( NULL ); // Tell everyone to detach them CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false ); g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket ); // Execute the attach trailer script function CLuaArguments Arguments; Arguments.PushElement ( pTowedByVehicle ); pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments ); } // If something else is towing this trailer CVehicle* pCurrentVehicle = pTrailer->GetTowedByVehicle (); if ( pCurrentVehicle ) { pCurrentVehicle->SetTowedVehicle ( NULL ); pTrailer->SetTowedByVehicle ( NULL ); // Tell everyone to detach them CVehicleTrailerPacket AttachPacket ( pCurrentVehicle, pTrailer, false ); g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket ); // Execute the attach trailer script function CLuaArguments Arguments; Arguments.PushElement ( pCurrentVehicle ); pTrailer->CallEvent ( "onTrailerDetach", Arguments ); } pTowedByVehicle->SetTowedVehicle ( pTrailer ); pTrailer->SetTowedByVehicle ( pTowedByVehicle ); // Execute the attach trailer script function CLuaArguments Arguments; Arguments.PushElement ( pTowedByVehicle ); bool bContinue = pTrailer->CallEvent ( "onTrailerAttach", Arguments ); // Attach or detach trailers depending on the event outcome CVehicleTrailerPacket TrailerPacket ( pTowedByVehicle, pTrailer, bContinue ); g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( TrailerPacket ); } } else break; pTowedByVehicle = pTrailer; if ( BitStream.ReadBit ( bHasTrailer ) == false ) return false; } // If there was a trailer before CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle (); if ( pCurrentTrailer ) { pTowedByVehicle->SetTowedVehicle ( NULL ); pCurrentTrailer->SetTowedByVehicle ( NULL ); // Tell everyone else to detach them CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false ); g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket ); // Execute the detach trailer script function CLuaArguments Arguments; Arguments.PushElement ( pTowedByVehicle ); pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments ); } } // Player health SPlayerHealthSync health; if ( !BitStream.Read ( &health ) ) return false; float fHealth = health.data.fValue; float fOldHealth = pSourcePlayer->GetHealth (); float fHealthLoss = fOldHealth - fHealth; // Less than last packet's frame? if ( fHealth < fOldHealth && fHealthLoss > 0 ) { // Call the onPlayerDamage event CLuaArguments Arguments; Arguments.PushNil (); Arguments.PushNumber ( false ); Arguments.PushNumber ( false ); Arguments.PushNumber ( fHealthLoss ); pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments ); } pSourcePlayer->SetHealth ( fHealth ); // Armor SPlayerArmorSync armor; if ( !BitStream.Read ( &armor ) ) return false; float fArmor = armor.data.fValue; float fOldArmor = pSourcePlayer->GetArmor (); float fArmorLoss = fOldArmor - fArmor; // Less than last packet's frame? if ( fArmor < fOldArmor && fArmorLoss > 0 ) { // Call the onPlayerDamage event CLuaArguments Arguments; Arguments.PushNil (); Arguments.PushNumber ( false ); Arguments.PushNumber ( false ); Arguments.PushNumber ( fArmorLoss ); pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments ); } pSourcePlayer->SetArmor ( fArmor ); // Flags SVehiclePuresyncFlags flags; if ( !BitStream.Read ( &flags ) ) return false; pSourcePlayer->SetWearingGoggles ( flags.data.bIsWearingGoggles ); pSourcePlayer->SetDoingGangDriveby ( flags.data.bIsDoingGangDriveby ); // Weapon sync if ( flags.data.bHasAWeapon ) { SWeaponSlotSync slot; if ( !BitStream.Read ( &slot ) ) return false; pSourcePlayer->SetWeaponSlot ( slot.data.uiSlot ); if ( flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo ( slot.data.uiSlot ) ) { // Read the ammo states SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), false, true ); if ( !BitStream.Read ( &ammo ) ) return false; pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip ); // Read aim data SWeaponAimSync aim ( pSourcePlayer->GetWeaponRange (), true ); if ( !BitStream.Read ( &aim ) ) return false; pSourcePlayer->SetAimDirection ( aim.data.fArm ); pSourcePlayer->SetSniperSourceVector ( aim.data.vecOrigin ); pSourcePlayer->SetTargettingVector ( aim.data.vecTarget ); // Read the driveby direction SDrivebyDirectionSync driveby; if ( !BitStream.Read ( &driveby ) ) return false; pSourcePlayer->SetDriveByDirection ( driveby.data.ucDirection ); } } else pSourcePlayer->SetWeaponSlot ( 0 ); // Vehicle specific data if he's the driver if ( uiSeat == 0 ) { ReadVehicleSpecific ( pVehicle, BitStream ); // Set vehicle specific stuff if he's the driver pVehicle->SetSirenActive ( flags.data.bIsSirenOrAlarmActive ); pVehicle->SetSmokeTrailEnabled ( flags.data.bIsSmokeTrailEnabled ); pVehicle->SetLandingGearDown ( flags.data.bIsLandingGearDown ); pVehicle->SetOnGround ( flags.data.bIsOnGround ); pVehicle->SetInWater ( flags.data.bIsInWater ); pVehicle->SetDerailed ( flags.data.bIsDerailed ); pVehicle->SetHeliSearchLightVisible ( flags.data.bIsHeliSearchLightVisible ); } // Read the vehicle_look_left and vehicle_look_right control states // if it's an aircraft. if ( flags.data.bIsAircraft ) { ControllerState.LeftShoulder2 = BitStream.ReadBit () * 255; ControllerState.RightShoulder2 = BitStream.ReadBit () * 255; } pSourcePlayer->GetPad ()->NewControllerState ( ControllerState ); // Success return true; } } return false; }
int CLuaFunctionDefs::Load( lua_State* luaVM ) { // func,err load( callback callbackFunction[, string name] ) CLuaFunctionRef iLuaFunction; SString strName; CScriptArgReader argStream( luaVM ); argStream.ReadFunction( iLuaFunction ); argStream.ReadString( strName, "=(load)" ); argStream.ReadFunctionComplete(); if ( !argStream.HasErrors() ) { // Call supplied function to get all the bits // Should apply some limit here? SString strInput; CLuaArguments callbackArguments; CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine( luaVM ); while( pLuaMain ) { CLuaArguments returnValues; callbackArguments.Call( pLuaMain, iLuaFunction, &returnValues ); if ( returnValues.Count() ) { CLuaArgument* returnedValue = *returnValues.IterBegin(); if ( returnedValue->GetType() == LUA_TSTRING ) { strInput += returnedValue->GetString(); continue; } } break; } const char* szChunkname = *strName; const char* cpInBuffer = strInput; uint uiInSize = strInput.length(); // Decrypt if required const char* cpBuffer; uint uiSize; if ( !g_pNet->DecryptScript( cpInBuffer, uiInSize, &cpBuffer, &uiSize, m_pResourceManager->GetResourceName( luaVM ) + "/load" ) ) { SString strMessage( "argument 2 is invalid. Please re-compile at http://luac.mtasa.com/", 0 ); argStream.SetCustomError( strMessage ); cpBuffer = NULL; g_pCore->GetConsole()->Print( argStream.GetFullErrorMessage() ); g_pClientGame->TellServerSomethingImportant( 1005, argStream.GetFullErrorMessage(), true ); } if ( !argStream.HasErrors() ) { CLuaShared::CheckUTF8BOMAndUpdate ( &cpBuffer, &uiSize ); if ( !CLuaMain::LuaLoadBuffer( luaVM, cpBuffer, uiSize, szChunkname ) ) { // Ok return 1; } else { lua_pushnil( luaVM ); lua_insert( luaVM, -2 ); /* put before error message */ return 2; /* return nil plus error message */ } } } if ( argStream.HasErrors() ) m_pScriptDebugging->LogCustom( luaVM, argStream.GetFullErrorMessage() ); lua_pushboolean( luaVM, false ); return 1; }
void CClientWebBrowser::Events_OnDocumentReady ( const SString& strURL ) { CLuaArguments Arguments; Arguments.PushString ( strURL ); CallEvent ( "onClientBrowserDocumentReady", Arguments, false ); }