You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
8.4 KiB
322 lines
8.4 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#include "plNetObjectDebugger.h" |
|
#include "hsResMgr.h" |
|
#include "hsTemplates.h" |
|
|
|
#include "pnUtils/pnUtils.h" |
|
#include "pnKeyedObject/hsKeyedObject.h" |
|
|
|
#include "plStatusLog/plStatusLog.h" |
|
#include "plResMgr/plKeyFinder.h" |
|
#include "plNetClient/plNetClientMgr.h" |
|
#include "plAgeLoader/plAgeLoader.h" |
|
|
|
plNetObjectDebugger::DebugObject::DebugObject(const char* objName, plLocation& loc, UInt32 flags) : |
|
fLoc(loc), |
|
fFlags(flags) |
|
{ |
|
std::string tmp = objName; |
|
hsStrLower((char*)tmp.c_str()); |
|
fObjName = tmp; |
|
} |
|
|
|
// |
|
// return true if string matches objName according to flags |
|
// |
|
bool plNetObjectDebugger::DebugObject::StringMatches(const char* str) const |
|
{ |
|
if (!str) |
|
return false; |
|
|
|
if (fFlags & kExactStringMatch) |
|
return !stricmp(str, fObjName.c_str()); |
|
|
|
if (fFlags & kEndStringMatch) |
|
{ |
|
int len=strlen(str); |
|
if (len>fObjName.size()) |
|
return false; |
|
return !stricmp(str, fObjName.c_str()+fObjName.size()-len); |
|
} |
|
|
|
if (fFlags & kStartStringMatch) |
|
{ |
|
int len=strlen(str); |
|
if (len>fObjName.size()) |
|
return false; |
|
return !strnicmp(str, fObjName.c_str(), strlen(str)); |
|
} |
|
|
|
if (fFlags & kSubStringMatch) |
|
{ |
|
std::string tmp = str; |
|
hsStrLower((char*)tmp.c_str()); |
|
return (strstr(tmp.c_str(), fObjName.c_str()) != nil); |
|
} |
|
|
|
hsAssert(false, "missing flags"); |
|
return false; |
|
} |
|
|
|
// |
|
// if both objName and pageName are provided, and this object has page info, |
|
// return true if object matches both string and location. |
|
// else just return true if object matches string |
|
// |
|
bool plNetObjectDebugger::DebugObject::ObjectMatches(const char* objName, const char* pageName) |
|
{ |
|
if (!objName) |
|
return false; |
|
|
|
if (!pageName || (fFlags & kPageMatch)==0) |
|
{ |
|
// only have enough info to match by objName |
|
return StringMatches(objName); |
|
} |
|
|
|
plLocation loc; |
|
loc = plKeyFinder::Instance().FindLocation(NetCommGetAge()->ageDatasetName, pageName); |
|
return (StringMatches(objName) && loc==fLoc); |
|
} |
|
|
|
// |
|
// try to match by plLocation |
|
// |
|
bool plNetObjectDebugger::DebugObject::ObjectMatches(const hsKeyedObject* obj) |
|
{ |
|
if (!obj || !obj->GetKey()) |
|
return false; |
|
|
|
if ((fFlags & kPageMatch)==0) |
|
{ |
|
// match based on object name only |
|
return StringMatches(obj->GetKeyName()); |
|
} |
|
|
|
return (obj->GetKey()->GetUoid().GetLocation()==fLoc); |
|
} |
|
|
|
///////////////////////////////////////////////////////////////// |
|
// plNetObjectDebugger |
|
///////////////////////////////////////////////////////////////// |
|
plNetObjectDebugger::plNetObjectDebugger() : fStatusLog(nil), fDebugging(false) |
|
{ |
|
} |
|
|
|
plNetObjectDebugger::~plNetObjectDebugger() |
|
{ |
|
ClearAllDebugObjects(); |
|
delete fStatusLog; |
|
} |
|
|
|
// |
|
// STATIC |
|
// |
|
plNetObjectDebugger* plNetObjectDebugger::GetInstance() |
|
{ |
|
static plNetObjectDebugger gNetObjectDebugger; |
|
|
|
if (plNetObjectDebuggerBase::GetInstance()==nil) |
|
plNetObjectDebuggerBase::SetInstance(&gNetObjectDebugger); |
|
|
|
return &gNetObjectDebugger; |
|
} |
|
|
|
// |
|
// create StatusLog if necessary |
|
// |
|
void plNetObjectDebugger::ICreateStatusLog() const |
|
{ |
|
if (!fStatusLog) |
|
{ |
|
fStatusLog = plStatusLogMgr::GetInstance().CreateStatusLog(40, "NetObject.log", |
|
plStatusLog::kFilledBackground | plStatusLog::kAlignToTop | plStatusLog::kTimestamp ); |
|
} |
|
} |
|
|
|
bool plNetObjectDebugger::AddDebugObject(const char* objName, const char* pageName) |
|
{ |
|
if (!objName) |
|
return false; |
|
|
|
int size=strlen(objName)+1; |
|
hsTempArray<char> tmpObjName(size); |
|
memset(tmpObjName, 0, size); |
|
|
|
// |
|
// set string matching flags |
|
// |
|
int len = strlen(objName); |
|
UInt32 flags=0; |
|
if (objName[0]=='*') |
|
{ |
|
if (objName[len-1]=='*') |
|
{ |
|
flags = kSubStringMatch; // *foo* |
|
strncpy(tmpObjName, objName+1, strlen(objName)-2); |
|
} |
|
else |
|
{ |
|
flags = kEndStringMatch; // *foo |
|
strncpy(tmpObjName, objName+1, strlen(objName)-1); |
|
} |
|
} |
|
|
|
if (!flags && objName[len-1]=='*') |
|
{ |
|
flags = kStartStringMatch; // foo* |
|
strncpy(tmpObjName, objName, strlen(objName)-1); |
|
} |
|
|
|
if (!flags) |
|
{ |
|
flags = kExactStringMatch; |
|
strcpy(tmpObjName, objName); |
|
} |
|
|
|
// |
|
// set plLocation |
|
// |
|
plLocation loc; |
|
if (pageName) |
|
{ |
|
loc = plKeyFinder::Instance().FindLocation(NetCommGetAge()->ageDatasetName, pageName); |
|
flags |= kPageMatch; |
|
} |
|
|
|
fDebugObjects.push_back(TRACKED_NEW DebugObject(tmpObjName, loc, flags)); |
|
|
|
ICreateStatusLog(); |
|
|
|
return true; |
|
} |
|
|
|
bool plNetObjectDebugger::RemoveDebugObject(const char* objName, const char* pageName) |
|
{ |
|
bool didIt=false; |
|
if (!pageName) |
|
{ |
|
DebugObjectList::iterator it =fDebugObjects.begin(); |
|
for( ; it != fDebugObjects.end(); ) |
|
{ |
|
if ( (*it) && (*it)->ObjectMatches(objName, pageName)) |
|
{ |
|
delete *it; |
|
it = fDebugObjects.erase(it); |
|
didIt=true; |
|
} |
|
else |
|
it++; |
|
} |
|
} |
|
|
|
return didIt; |
|
} |
|
|
|
void plNetObjectDebugger::ClearAllDebugObjects() |
|
{ |
|
DebugObjectList::iterator it =fDebugObjects.begin(); |
|
for( ; it != fDebugObjects.end(); it++) |
|
{ |
|
delete *it; |
|
} |
|
fDebugObjects.clear(); |
|
} |
|
|
|
// |
|
// write to status log if there's a string match |
|
// |
|
void plNetObjectDebugger::LogMsgIfMatch(const char* msg) const |
|
{ |
|
if (GetNumDebugObjects()==0 || !msg) |
|
return; |
|
|
|
// extract object name from msg, expects '...object:foo,...' |
|
std::string tmp = msg; |
|
hsStrLower((char*)tmp.c_str()); |
|
std::string objTag="object"; |
|
const char* c=strstr(tmp.c_str(), objTag.c_str()); |
|
if (c && c != tmp.c_str()) |
|
{ |
|
c+=objTag.size(); |
|
|
|
// move past spaces |
|
while ( *c || *c==' ' ) |
|
c++; |
|
|
|
char objName[128]; |
|
int i=0; |
|
|
|
// copy objName token |
|
while(*c && *c != ',' && *c != ' ' && i<127) |
|
objName[i++] = *c++; |
|
objName[i]=0; |
|
|
|
DebugObjectList::const_iterator it = fDebugObjects.begin(); |
|
for( objName[0]; it != fDebugObjects.end(); it++) |
|
{ |
|
if ((*it) && (*it)->StringMatches(objName)) |
|
{ |
|
LogMsg(msg); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
void plNetObjectDebugger::LogMsg(const char* msg) const |
|
{ |
|
DEBUG_MSG(msg); |
|
} |
|
|
|
bool plNetObjectDebugger::IsDebugObject(const hsKeyedObject* obj) const |
|
{ |
|
DebugObjectList::const_iterator it =fDebugObjects.begin(); |
|
for( ; it != fDebugObjects.end(); it++) |
|
if ((*it) && (*it)->ObjectMatches(obj)) |
|
{ |
|
return true; |
|
} |
|
|
|
return false; |
|
}
|
|
|