You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
5.5 KiB
C++
192 lines
5.5 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
// Description : Remote command system implementation
|
|
|
|
#include "CrySystem_precompiled.h"
|
|
#include "IServiceNetwork.h"
|
|
#include "RemoteCommand.h"
|
|
#include "RemoteCommandHelpers.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// remote system internal logging
|
|
#ifdef RELEASE
|
|
#define LOG_VERBOSE(level, txt, ...)
|
|
#else
|
|
#define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); }
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CRemoteCommandManager::CRemoteCommandManager()
|
|
{
|
|
// Create the CVAR
|
|
m_pVerboseLevel = gEnv->pConsole->RegisterInt("rc_debugVerboseLevel", 0, VF_DEV_ONLY);
|
|
}
|
|
|
|
CRemoteCommandManager::~CRemoteCommandManager()
|
|
{
|
|
// Release the CVar
|
|
if (NULL != m_pVerboseLevel)
|
|
{
|
|
m_pVerboseLevel->Release();
|
|
m_pVerboseLevel = NULL;
|
|
}
|
|
}
|
|
|
|
IRemoteCommandServer* CRemoteCommandManager::CreateServer(uint16 localPort)
|
|
{
|
|
// Create the listener
|
|
IServiceNetworkListener* listener = gEnv->pServiceNetwork->CreateListener(localPort);
|
|
if (NULL == listener)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Create the wrapper
|
|
return new CRemoteCommandServer(this, listener);
|
|
}
|
|
|
|
IRemoteCommandClient* CRemoteCommandManager::CreateClient()
|
|
{
|
|
// Create the wrapper
|
|
return new CRemoteCommandClient(this);
|
|
}
|
|
|
|
void CRemoteCommandManager::RegisterCommandClass(IRemoteCommandClass& commandClass)
|
|
{
|
|
// Make sure command class is not already registered
|
|
const string& className(commandClass.GetName());
|
|
TClassMap::const_iterator it = m_pClasses.find(className);
|
|
if (it != m_pClasses.end())
|
|
{
|
|
LOG_VERBOSE(1, "Class '%s' is already registered",
|
|
className.c_str());
|
|
|
|
return;
|
|
}
|
|
|
|
const uint32 classID = m_pClassesByID.size();
|
|
m_pClassesByID.push_back(&commandClass);
|
|
m_pClassesMap[ className ] = classID;
|
|
m_pClasses[ className ] = &commandClass;
|
|
|
|
// Verbose
|
|
LOG_VERBOSE(1, "Registered command class '%s' with id %d",
|
|
className.c_str(),
|
|
classID);
|
|
}
|
|
|
|
#ifndef RELEASE
|
|
bool CRemoteCommandManager::CheckVerbose(const uint32 level) const
|
|
{
|
|
const int verboseLevel = m_pVerboseLevel->GetIVal();
|
|
return (int)level < verboseLevel;
|
|
}
|
|
|
|
void CRemoteCommandManager::Log(const char* txt, ...) const
|
|
{
|
|
// format the print buffer
|
|
char buffer[512];
|
|
va_list ap;
|
|
va_start(ap, txt);
|
|
vsprintf_s(buffer, sizeof(buffer), txt, ap);
|
|
va_end(ap);
|
|
|
|
// pass to log
|
|
gEnv->pLog->LogAlways(buffer);
|
|
}
|
|
#endif
|
|
|
|
void CRemoteCommandManager::BuildClassMapping(const std::vector<string>& classNames, std::vector< IRemoteCommandClass* >& outClasses)
|
|
{
|
|
LOG_VERBOSE(3, "Building class mapping for %d classes",
|
|
classNames.size());
|
|
|
|
// Output list size has the same size as class names array
|
|
const uint32 numClasses = classNames.size();
|
|
outClasses.resize(numClasses);
|
|
|
|
// Match the classes
|
|
for (size_t i = 0; i < numClasses; ++i)
|
|
{
|
|
// Find the matching class
|
|
const string& className = classNames[i];
|
|
TClassMap::const_iterator it = m_pClasses.find(className);
|
|
if (it != m_pClasses.end())
|
|
{
|
|
CRY_ASSERT(className == it->second->GetName());
|
|
CRY_ASSERT(it->second != NULL);
|
|
outClasses[i] = it->second;
|
|
|
|
// Report class mapping in heavy verbose mode
|
|
LOG_VERBOSE(3, "Class[%d] = %s",
|
|
i,
|
|
className.c_str());
|
|
}
|
|
else
|
|
{
|
|
outClasses[i] = NULL;
|
|
|
|
// Class not mapped (this can cause errors)
|
|
LOG_VERBOSE(0, "Remote command class '%s' not found on this machine",
|
|
className.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
void CRemoteCommandManager::SetVerbosityLevel(const uint32 level)
|
|
{
|
|
// propagate the value to CVar (so it is consistent across the engine)
|
|
if (NULL != m_pVerboseLevel)
|
|
{
|
|
m_pVerboseLevel->Set((int)level);
|
|
}
|
|
}
|
|
|
|
void CRemoteCommandManager::GetClassList(std::vector<string>& outClassNames) const
|
|
{
|
|
const uint32 numClasses = m_pClassesByID.size();
|
|
outClassNames.resize(numClasses);
|
|
for (size_t id = 0; id < numClasses; ++id)
|
|
{
|
|
IRemoteCommandClass* theClass = m_pClassesByID[id];
|
|
if (NULL != theClass)
|
|
{
|
|
outClassNames[id] = theClass->GetName();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CRemoteCommandManager::FindClassId(IRemoteCommandClass* commandClass, uint32& outClassId) const
|
|
{
|
|
// Local search (linear, slower)
|
|
TClassIDMap::const_iterator it = m_pClassesMap.find(commandClass->GetName());
|
|
if (it != m_pClassesMap.end())
|
|
{
|
|
outClassId = it->second;
|
|
return true;
|
|
}
|
|
|
|
// Not found
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Do not remove (can mess up the uber file builds)
|
|
#undef LOG_VERBOSE
|
|
|
|
//-----------------------------------------------------------------------------
|