#include "stdafx.h" #include #include "PrintLog.h" #include "SearchClass.h" #include "LogAnalyzer.h" #include #include "GlobalFunctions.h" #include "XListBox.h" #include "CheckComboBox.h" #include // edith 2009.08.11 °ÔÀÓ°¡µå 2.5 ¾÷±×·¹À̵å GGAUTHS_API void NpLog(int mode, char* msg) { } GGAUTHS_API void GGAuthUpdateCallback(PGG_UPREPORT report) { } struct CategoryInfo { typedef void PrintSimpleInfo(CString& Result, const GAMELOG::sLogBase* lpLogBase); const char* m_szCategoryName; unsigned char m_cCmd; CXListBox::Color m_nFGColor; CXListBox::Color m_nBGColor; PrintSimpleInfo* m_lpSimpleInfo; CategoryInfo() : m_szCategoryName(0), m_cCmd(0), m_nFGColor(CXListBox::Black), m_nBGColor(CXListBox::White), m_lpSimpleInfo(0) { } CategoryInfo(const char* szCategoryName, unsigned char cCmd, CXListBox::Color nFGColor, CXListBox::Color nBGColor, PrintSimpleInfo* lpSimpleInfo) : m_szCategoryName(szCategoryName), m_cCmd(cCmd), m_nFGColor(nFGColor), m_nBGColor(nBGColor), m_lpSimpleInfo(lpSimpleInfo) { } }; class CCategoryData { public: CCategoryData(); static CCategoryData& GetInstance(); CategoryInfo* GetCategoryInfo(unsigned char cCmd) { return cCmd < GAMELOG::CMD::MAX_LOGCMD ? m_categoryInfo + cCmd : 0; } CategoryInfo* GetCategoryInfo(const char* szText) { CategoryInfo* lpPos = m_categoryInfo; CategoryInfo* lpEnd = m_categoryInfo + GAMELOG::CMD::MAX_LOGCMD; for(; lpPos != lpEnd; ++lpPos) { if(0 != lpPos->m_szCategoryName && 0 == strcmp(lpPos->m_szCategoryName, szText)) { return lpPos; } } return 0; } private: CategoryInfo m_categoryInfo[GAMELOG::CMD::MAX_LOGCMD]; }; CCategoryData& CCategoryData::GetInstance() { static CCategoryData categoryData; return categoryData; } namespace GAMELOG { namespace CMD { const unsigned int ALL = 0; }; }; CCategoryData::CCategoryData() { using namespace GAMELOG::SimpleInfo; #define SET_CATEGORY_DATA(name, fgColor, bgColor, lpSimpleInfo) \ m_categoryInfo[GAMELOG::CMD::name] = \ CategoryInfo(#name, GAMELOG::CMD::name, fgColor, bgColor, lpSimpleInfo); SET_CATEGORY_DATA(ALL, CXListBox::Black, CXListBox::White, 0); SET_CATEGORY_DATA(CHAR_LOGIN, CXListBox::Yellow, CXListBox::Black, CharLogin); SET_CATEGORY_DATA(CHAR_LOGOUT, CXListBox::Yellow, CXListBox::Black, CharLogout); SET_CATEGORY_DATA(CHAR_CREATE, CXListBox::Black, CXListBox::White, CharCreate); SET_CATEGORY_DATA(CHAR_DELETE, CXListBox::Black, CXListBox::WhitePink, CharDelete); SET_CATEGORY_DATA(CHAR_DBUPDATE, CXListBox::Black, CXListBox::White, CharDBUpdate); SET_CATEGORY_DATA(CHAR_LEVELUP, CXListBox::Black, CXListBox::White, CharLevelUp); SET_CATEGORY_DATA(CHAR_BIND_POS, CXListBox::Black, CXListBox::White, CharBindPos); SET_CATEGORY_DATA(CHAR_DEAD, CXListBox::Black, CXListBox::WhitePink, CharDead); SET_CATEGORY_DATA(CHAR_RESPAWN, CXListBox::Black, CXListBox::White, CharRespawn); SET_CATEGORY_DATA(MOVE_ITEM, CXListBox::Black, CXListBox::White, MoveItem); SET_CATEGORY_DATA(SWAP_ITEM, CXListBox::Black, CXListBox::White, SwapItem); SET_CATEGORY_DATA(USE_ITEM, CXListBox::Black, CXListBox::White, UseItem); SET_CATEGORY_DATA(SPLIT_ITEM, CXListBox::Black, CXListBox::White, SplitItem); SET_CATEGORY_DATA(PICKUP_ITEM, CXListBox::Black, CXListBox::White, PickupItem); SET_CATEGORY_DATA(DROP_ITEM, CXListBox::Black, CXListBox::White, DropItem); SET_CATEGORY_DATA(BUY_ITEM, CXListBox::Black, CXListBox::White, BuyItem); SET_CATEGORY_DATA(SELL_ITEM, CXListBox::Black, CXListBox::White, SellItem); SET_CATEGORY_DATA(USE_LOTTERY, CXListBox::Black, CXListBox::White, UseLottery); SET_CATEGORY_DATA(BEFORE_EXCHANGE_ITEM, CXListBox::Black, CXListBox::Yellow, BeforeExchange); SET_CATEGORY_DATA(AFTER_EXCHANGE_ITEM, CXListBox::Black, CXListBox::Yellow, AfterExchange); SET_CATEGORY_DATA(INSTALL_SOCKET_ITEM, CXListBox::Black, CXListBox::White, InstallSocketItem); SET_CATEGORY_DATA(REPAIR_ITEM, CXListBox::Black, CXListBox::White, RepairItem); SET_CATEGORY_DATA(CHANGE_WEAPON, CXListBox::Black, CXListBox::White, ChangeWeapon); SET_CATEGORY_DATA(TAKE_GOLD, CXListBox::Black, CXListBox::White, TakeGold); SET_CATEGORY_DATA(UPGRADE_ITEM, CXListBox::Black, CXListBox::White, UpgradeItem); SET_CATEGORY_DATA(STALL_OPEN_CLOSE, CXListBox::Black, CXListBox::White, StallOpenClose); SET_CATEGORY_DATA(STALL_ENTER_LEAVE, CXListBox::Black, CXListBox::White, StallEnterLeave); SET_CATEGORY_DATA(STALL_ITEM_REGISTER_REMOVE, CXListBox::Black, CXListBox::White, StallRegisterRemoveItem); SET_CATEGORY_DATA(MEDAL_BUY_ITEM, CXListBox::Black, CXListBox::White, MedalItemBuy); SET_CATEGORY_DATA(TAKE_GOLD_V2, CXListBox::Black, CXListBox::White, TakeGoldV2); SET_CATEGORY_DATA(GUILD_CREATE, CXListBox::Black, CXListBox::White, GuildCreate); SET_CATEGORY_DATA(GUILD_JOIN, CXListBox::Black, CXListBox::White, GuildJoin); SET_CATEGORY_DATA(GUILD_MEMBER_LEVEL, CXListBox::Black, CXListBox::White, GuildMemberLevelAdjust); SET_CATEGORY_DATA(GUILD_LEAVE, CXListBox::Black, CXListBox::White, GuildLeave); SET_CATEGORY_DATA(GUILD_RIGHTS_CHANGE, CXListBox::Black, CXListBox::White, GuildRightsLevelChange); SET_CATEGORY_DATA(GUILD_LEVEL_ADJUST, CXListBox::Black, CXListBox::White, GuildLevelChange); SET_CATEGORY_DATA(GUILD_MARK_ADJUST, CXListBox::Black, CXListBox::White, GuildMarkChange); SET_CATEGORY_DATA(GUILD_GOLD_CHANGE, CXListBox::Black, CXListBox::Yellow, GuildStoreGoldChange); SET_CATEGORY_DATA(GUILD_DISSOLVE, CXListBox::Black, CXListBox::White, GuildDispose); SET_CATEGORY_DATA(ZONE_MOVE, CXListBox::Black, CXListBox::White, ZoneMoveLog); SET_CATEGORY_DATA(ITEM_ATTACH_OPTION, CXListBox::Black, CXListBox::White, ItemAttachOption); SET_CATEGORY_DATA(ITEM_COMPENSATION, CXListBox::Black, CXListBox::SkyBlue, ItemCompensation); SET_CATEGORY_DATA(TICKET_BUY_SKILLBOOK, CXListBox::Black, CXListBox::White, TicketBuySkillBook); SET_CATEGORY_DATA(UPGRADE_ITEM_V2, CXListBox::Black, CXListBox::White, UpgradeItemV2); SET_CATEGORY_DATA(MONSTER_DEAD, CXListBox::Black, CXListBox::White, MonsterDead); SET_CATEGORY_DATA(FAME_GET_BATTLE, CXListBox::Black, CXListBox::White, FameGetBattle); SET_CATEGORY_DATA(FAME_LOSE_BATTLE, CXListBox::Black, CXListBox::White, FameLoseBattle); SET_CATEGORY_DATA(FAME_GET_CAMP, CXListBox::Black, CXListBox::White, FameGetCamp); SET_CATEGORY_DATA(FAME_LOSE_CAMP, CXListBox::Black, CXListBox::White, FameLoseCamp); SET_CATEGORY_DATA(QUEST_GET_REWARD, CXListBox::Black, CXListBox::White, QuestGetReward); SET_CATEGORY_DATA(CHANGE_RIDE, CXListBox::Black, CXListBox::White, ChangeRide); SET_CATEGORY_DATA(ILLEGAL_ITEM, CXListBox::White, CXListBox::Red, IllegalItem); SET_CATEGORY_DATA(ILLEGAL_WARPPOS, CXListBox::White, CXListBox::Red, IllegalWarpPos); SET_CATEGORY_DATA(HACK_DOUBT, CXListBox::White, CXListBox::Red, HackDoubt); }; CLogAnalyzer::CLogAnalyzer() : m_nCurrentIndex(0), m_dwShowMode(0) { m_ResultArray.reserve(5120); memset(m_szFileName, 0, MAX_PATH); } CLogAnalyzer::~CLogAnalyzer() { Cleanup(); } bool CLogAnalyzer::Initialize(HWND hWnd_In, CComboBox& SearchSort_Out, CCheckComboBox& Category_Out) { if(CB_ERR == SearchSort_Out.InsertString(0, "CID")) { return false; } if(CB_ERR == SearchSort_Out.InsertString(1, "UID")) { return false; } if(CB_ERR == SearchSort_Out.InsertString(2, "ItemUID")) { return false; } if(CB_ERR == SearchSort_Out.InsertString(3, "IP")) { return false; } if(CB_ERR == SearchSort_Out.InsertString(4, "ItemTypeID")) { return false; } if(CB_ERR == SearchSort_Out.InsertString(5, "GID")) { return false; } if(CB_ERR == SearchSort_Out.SetCurSel(0)) { return false; } unsigned char nCount = 0; unsigned char nStringNum = 0; for(; nCount < GAMELOG::CMD::MAX_LOGCMD; ++nCount) { CategoryInfo* lpInfo = CCategoryData::GetInstance().GetCategoryInfo(nCount); if(0 != lpInfo && 0 != lpInfo->m_szCategoryName) { if(CB_ERR == Category_Out.InsertString(nStringNum, lpInfo->m_szCategoryName)) { return false; } Category_Out.SetItemData(nStringNum, nCount); ++nStringNum; } } if(CB_ERR == Category_Out.SetCurSel(0)) { return false; } memset(&m_OpenFile, 0, sizeof(OPENFILENAME)); m_OpenFile.lStructSize = sizeof(OPENFILENAME); m_OpenFile.hwndOwner = hWnd_In; m_OpenFile.lpstrFilter = "Log and ziped files\0*.zip;*.log\0All files\0*.*"; m_OpenFile.nMaxFile = MAX_PATH * MAX_PATH; m_OpenFile.Flags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER; m_OpenFile.lpstrFile = m_szFileName; return true; } bool CLogAnalyzer::Cleanup() { m_nCurrentIndex = 0; m_ResultArray.clear(); return true; } bool CLogAnalyzer::Open() { Cleanup(); ZeroMemory(m_szFileName, MAX_PATH); //if(!GetOpenFileName(&m_OpenFile)) //{ // return false; //} if (GetOpenFileName(&m_OpenFile)) return m_ParseLog.LoadFile(m_szFileName); return true; } bool CLogAnalyzer::Search(CCheckComboBox& categoryValue_In, const CString& SearchType_In, const CString& SearchValue_In, const CTime& StartTime, const CTime& StopTime, const CRegion& Region, const BOOL bSearchInResult) { m_nCurrentIndex = 0; return Search(m_ParseLog, m_ResultArray, categoryValue_In, SearchType_In, SearchValue_In, StartTime, StopTime, Region, bSearchInResult); } bool CLogAnalyzer::Search(CParseLog& ParseLog, CParseLog::LogPtrArray& ResultArray, CCheckComboBox& categoryValue_In, const CString& SearchType_In, const CString& SearchValue_In, const CTime& StartTime, const CTime& StopTime, const CRegion& Region, const BOOL bSearchInResult) { CParseLog::LogPtrArray Result; // ½Ã°£´ë °Ë»ö if(bSearchInResult) { CParseLog::Find(ResultArray, Result, CTimeSearch(StartTime, StopTime)); ResultArray.swap(Result); } else { ParseLog.Find(ResultArray, CTimeSearch(StartTime, StopTime)); } // Çൿ¹Ý°æ °Ë»ö if(Region.IsValid()) { CParseLog::Find(ResultArray, Result, CPositionSearch(Region)); ResultArray.swap(Result); } // CID, UID, ItemUID, ItemTypeID ·Î °Ë»ö if(0 == SearchType_In.Compare("CID")) { CParseLog::Find(ResultArray, Result, CCIDSearch(SearchValue_In)); ResultArray.swap(Result); } else if(0 == SearchType_In.Compare("UID")) { CParseLog::Find(ResultArray, Result, CUIDSearch(SearchValue_In)); ResultArray.swap(Result); } else if(0 == SearchType_In.Compare("ItemUID")) { CParseLog::Find(ResultArray, Result, CItemUIDSearch(SearchValue_In)); ResultArray.swap(Result); } else if(0 == SearchType_In.Compare("IP")) { CParseLog::Find(ResultArray, Result, CIPSearch(SearchValue_In)); ResultArray.swap(Result); } else if(0 == SearchType_In.Compare("ItemTypeID")) { CParseLog::Find(ResultArray, Result, CItemTypeIDSearch(SearchValue_In)); ResultArray.swap(Result); } else if(0 == SearchType_In.Compare("GID")) { CParseLog::Find(ResultArray, Result, CGIDSearch(SearchValue_In)); ResultArray.swap(Result); } // ALLÀÌ Ã¼Å©µÇ¾î ÀÖÁö ¾ÊÀ¸¸é Àç°Ë»ö. int nCount = categoryValue_In.FindString(0, "ALL"); if(CB_ERR != nCount) { if(!categoryValue_In.GetCheck(nCount)) { CString strText; CCategory::CMDArray CMDArray; for(int nIndex = 0; nIndex < categoryValue_In.GetCount(); ++nIndex) { if (categoryValue_In.GetCheck(nIndex)) { categoryValue_In.GetLBText(nIndex, strText); if(!strText.IsEmpty()) { CategoryInfo* lpCategoryInfo = CCategoryData::GetInstance().GetCategoryInfo(strText); if(lpCategoryInfo) { CMDArray.push_back(lpCategoryInfo->m_cCmd); } } } } std::sort(CMDArray.begin(), CMDArray.end()); CParseLog::Find(ResultArray, Result, CCategory(CMDArray)); ResultArray.swap(Result); } } return true; } void CLogAnalyzer::Prev(CXListBox& Result, const size_t nShowNum, CString& Page) { if(m_nCurrentIndex > nShowNum) { m_nCurrentIndex -= nShowNum; Show(Result, nShowNum, Page); } } void CLogAnalyzer::Next(CXListBox& Result, const size_t nShowNum, CString& Page) { if(m_nCurrentIndex + nShowNum < m_ResultArray.size()) { m_nCurrentIndex += nShowNum; Show(Result, nShowNum, Page); } } void CLogAnalyzer::MovePage(CXListBox& Result, const size_t nShowNum, CString& Page, unsigned int dwPageIndex) { if((nShowNum * dwPageIndex) < (m_ResultArray.size() + nShowNum)) { m_nCurrentIndex = 0; m_nCurrentIndex = nShowNum * (dwPageIndex - 1); Show(Result, nShowNum, Page); } } void CLogAnalyzer::SetShowMode(const BOOL bShowUID, const BOOL bShowCID, const BOOL bShowTime, const BOOL bShowPosition) { m_dwShowMode = 0; if(bShowUID) { m_dwShowMode = m_dwShowMode | GAMELOG::UID; } if(bShowCID) { m_dwShowMode = m_dwShowMode | GAMELOG::CID; } if(bShowTime) { m_dwShowMode = m_dwShowMode | GAMELOG::TIME; } if(bShowPosition) { m_dwShowMode = m_dwShowMode | GAMELOG::POS; } } void CLogAnalyzer::Show(CXListBox& Result, const size_t nShowNum, CString& Page) { using namespace GAMELOG; Result.ResetContent(); CXListBox::Color nBackColor = CXListBox::White; CXListBox::Color nTextColor = CXListBox::Black; CString LogLine; CSize LogLineSize; int nMaxSizeX = 0; CDC* lpDC = Result.GetDC(); TEXTMETRIC tm; lpDC->GetTextMetrics(&tm); size_t nMaxShowNum = (m_ResultArray.size() < m_nCurrentIndex + nShowNum) ? m_ResultArray.size() : m_nCurrentIndex + nShowNum; CParseLog::LogPtrArray::iterator begin = m_ResultArray.begin() + m_nCurrentIndex; CParseLog::LogPtrArray::iterator end = m_ResultArray.begin() + nMaxShowNum; CCategoryData& categoryData = CCategoryData::GetInstance(); for(int nCount = 0; begin != end; ++begin, ++nCount) { const sLogBase* lpLogBase = *begin; LogLine = ""; SimpleInfo::BaseLog(LogLine, lpLogBase, m_dwShowMode); nBackColor = CXListBox::White; nTextColor = CXListBox::Black; if(lpLogBase->m_cCmd < GAMELOG::CMD::MAX_LOGCMD) { CategoryInfo* lpInfo = categoryData.GetCategoryInfo(lpLogBase->m_cCmd); if(0 != lpInfo && 0 != lpInfo->m_lpSimpleInfo) { lpInfo->m_lpSimpleInfo(LogLine, lpLogBase); nTextColor = lpInfo->m_nFGColor; nBackColor = lpInfo->m_nBGColor; } } if(0 != LogLine.GetString()) { LogLineSize = lpDC->GetTextExtent(LogLine); LogLineSize.cx += tm.tmAveCharWidth; if(LogLineSize.cx > nMaxSizeX) { nMaxSizeX = LogLineSize.cx; } Result.AddLine(nTextColor, nBackColor, LogLine); } } Result.ReleaseDC(lpDC); Result.SetHorizontalExtent(nMaxSizeX); Page.Format(GetMyINIString("STRING_FOR_LOCALIZE", "FORMAT_002"), m_nCurrentIndex/nShowNum + 1, m_ResultArray.size()/nShowNum + 1); } bool CLogAnalyzer::ShowDetail(int nSelect) { using namespace GAMELOG; CParseLog::LogPtrArray::size_type nIndex = nSelect + m_nCurrentIndex; if(nIndex >= m_ResultArray.size()) { return false; } sLogBase* lpLogBase = m_ResultArray[nIndex]; CString DetailString; switch(lpLogBase->m_cCmd) { case CMD::CHAR_LOGIN: case CMD::CHAR_LOGOUT: case CMD::CHAR_DBUPDATE: DetailInfo::ShowCharacterInfo(lpLogBase); break; case CMD::CHAR_CREATE: DetailInfo::CharCreate(lpLogBase); break; case CMD::CHAR_DELETE: DetailInfo::CharDelete(lpLogBase); break; case CMD::CHAR_LEVELUP: DetailInfo::CharLevelUp(lpLogBase); break; case CMD::CHAR_BIND_POS: DetailInfo::CharBindPos(lpLogBase); break; case CMD::CHAR_DEAD: DetailInfo::CharDead(lpLogBase); break; case CMD::CHAR_RESPAWN: DetailInfo::CharRespawn(lpLogBase); break; case CMD::MOVE_ITEM: DetailInfo::MoveItem(lpLogBase); break; case CMD::SWAP_ITEM: DetailInfo::SwapItem(lpLogBase); break; case CMD::USE_ITEM: DetailInfo::UseItem(lpLogBase); break; case CMD::SPLIT_ITEM: DetailInfo::SplitItem(lpLogBase); break; case CMD::PICKUP_ITEM: DetailString = GetMyINIString("STRING_FOR_LOCALIZE", "PICKUP_ITEM"); DetailInfo::PickupItem(DetailString, lpLogBase); break; case CMD::DROP_ITEM: DetailString = GetMyINIString("STRING_FOR_LOCALIZE", "DROP_ITEM"); DetailInfo::DropItem(DetailString, lpLogBase); break; case CMD::USE_LOTTERY: DetailInfo::UseLottery(lpLogBase); break; case CMD::SELL_ITEM: DetailString = GetMyINIString("STRING_FOR_LOCALIZE", "SELL_ITEM"); DetailInfo::TradeItem(DetailString, lpLogBase); break; case CMD::BUY_ITEM: DetailString = GetMyINIString("STRING_FOR_LOCALIZE", "BUY_ITEM"); DetailInfo::TradeItem(DetailString, lpLogBase); break; case CMD::BEFORE_EXCHANGE_ITEM: case CMD::AFTER_EXCHANGE_ITEM: DetailInfo::ExchangeItem(lpLogBase); break; case CMD::INSTALL_SOCKET_ITEM: DetailInfo::InstallSocketItem(lpLogBase); break; case CMD::REPAIR_ITEM: break; case CMD::CHANGE_WEAPON: break; case CMD::TAKE_GOLD: break; case CMD::UPGRADE_ITEM: DetailInfo::UpgradeItem(lpLogBase); break; case CMD::STALL_OPEN_CLOSE: break; case CMD::STALL_ENTER_LEAVE: break; case CMD::STALL_ITEM_REGISTER_REMOVE: break; case CMD::MEDAL_BUY_ITEM: DetailString = GetMyINIString("STRING_FOR_LOCALIZE", "MEDAL_BUY_ITEM"); DetailInfo::TradeItem(DetailString, lpLogBase); break; case CMD::GUILD_CREATE: case CMD::GUILD_JOIN: case CMD::GUILD_MEMBER_LEVEL: case CMD::GUILD_LEAVE: case CMD::GUILD_LEVEL_ADJUST: case CMD::GUILD_MARK_ADJUST: case CMD::GUILD_GOLD_CHANGE: case CMD::GUILD_DISSOLVE: break; case CMD::GUILD_RIGHTS_CHANGE: DetailInfo::GuildRightsChange(lpLogBase); break; case CMD::ZONE_MOVE: break; case CMD::ITEM_ATTACH_OPTION: DetailInfo::ItemAttachOption(lpLogBase); break; case CMD::ITEM_COMPENSATION: DetailInfo::ItemCompensation(lpLogBase); break; case CMD::TICKET_BUY_SKILLBOOK: DetailInfo::TradeItem(DetailString, lpLogBase); break; case CMD::UPGRADE_ITEM_V2: DetailInfo::UpgradeItemV2(lpLogBase); break; case CMD::MONSTER_DEAD: DetailInfo::MonsterDead(lpLogBase); break; case CMD::FAME_GET_BATTLE: case CMD::FAME_LOSE_BATTLE: case CMD::FAME_GET_CAMP: case CMD::FAME_LOSE_CAMP: case CMD::QUEST_GET_REWARD: break; case CMD::CHANGE_RIDE: break; case CMD::ILLEGAL_ITEM: break; case CMD::ILLEGAL_WARPPOS: break; case CMD::HACK_DOUBT: DetailString = GetMyINIString("STRING_FOR_LOCALIZE", "BUY_ITEM"); DetailInfo::HackDoubtItem(DetailString, lpLogBase); break; default: return false; } return true; } bool CLogAnalyzer::WriteTextLog(const char* szFileName) { CFile WriteFile(szFileName, CFile::modeWrite | CFile::modeCreate); CParseLog::LogPtrArray::iterator pos = m_ResultArray.begin(); CParseLog::LogPtrArray::iterator end = m_ResultArray.end(); CString LogLine; CCategoryData& categoryData = CCategoryData::GetInstance(); for(;pos != end;++pos) { const GAMELOG::sLogBase* lpLogBase = *pos; LogLine = ""; GAMELOG::SimpleInfo::BaseLog(LogLine, lpLogBase, m_dwShowMode); if(lpLogBase->m_cCmd < GAMELOG::CMD::MAX_LOGCMD) { CategoryInfo* lpInfo = categoryData.GetCategoryInfo(lpLogBase->m_cCmd); if(0 != lpInfo && 0 != lpInfo->m_lpSimpleInfo) { lpInfo->m_lpSimpleInfo(LogLine, lpLogBase); LogLine += "\n"; } } if(0 != LogLine.GetString()) { WriteFile.Write(LogLine, LogLine.GetLength()); } } return true; }