Files
Client/Server/ToolProject/GameLogAnalyzer/CharacterInfoDlg.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

296 lines
8.8 KiB
C++

// CharacterInfoDlg.cpp : 구현 파일입니다.
//
#include "stdafx.h"
#include "PrintLog.h"
#include "GAMELOGAnalyzer.h"
#include "CharacterInfoDlg.h"
#include "ItemInfoSheet.h"
#include "InfoDlg.h"
#include <BaseLibrary/Utility/Math/Math.h>
#include "GlobalFunctions.h"
// CCharacterInfoDlg 대화 상자입니다.
IMPLEMENT_DYNAMIC(CCharacterInfoDlg, CDialog)
CCharacterInfoDlg::CCharacterInfoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCharacterInfoDlg::IDD, pParent)
, m_LastPosX(_T(""))
, m_LastPosY(_T(""))
, m_LastPosZ(_T(""))
, m_SavePosX(_T(""))
, m_SavePosY(_T(""))
, m_SavePosZ(_T(""))
{
}
CCharacterInfoDlg::~CCharacterInfoDlg()
{
}
void CCharacterInfoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CHARACTER_STATUS_LIST, m_CharacterStatus);
DDX_Text(pDX, IDC_LAST_POSX, m_LastPosX);
DDX_Text(pDX, IDC_LAST_POSY, m_LastPosY);
DDX_Text(pDX, IDC_LAST_POSZ, m_LastPosZ);
DDX_Text(pDX, IDC_SAVE_POSX, m_SavePosX);
DDX_Text(pDX, IDC_SAVE_POSY, m_SavePosY);
DDX_Text(pDX, IDC_SAVE_POSZ, m_SavePosZ);
}
BEGIN_MESSAGE_MAP(CCharacterInfoDlg, CDialog)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_EXPORT_BUTTON, OnBnClickedItemInfo)
ON_BN_CLICKED(IDC_SHOW_QUICKSLOT, OnBnClickedShowQuickslot)
ON_BN_CLICKED(IDC_SHOW_SKILLSLOT, OnBnClickedShowSkillslot)
END_MESSAGE_MAP()
// CCharacterInfoDlg 메시지 처리기입니다.
void CCharacterInfoDlg::PostNcDestroy()
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
CDialog::PostNcDestroy();
delete this;
}
void CCharacterInfoDlg::OnClose()
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CDialog::OnClose();
DestroyWindow();
}
bool CCharacterInfoDlg::Initialize(const GAMELOG::sLogBase* lpLogBase)
{
using namespace GAMELOG;
m_dwCID = lpLogBase->m_dwCID;
m_dwUID = lpLogBase->m_dwUID;
m_time = lpLogBase->m_time;
switch(lpLogBase->m_cCmd)
{
case CMD::CHAR_LOGIN:
case CMD::CHAR_LOGOUT:
case CMD::CHAR_DBUPDATE:
{
const sCharLoginOut* pCharLoginOut = static_cast<const sCharLoginOut*>(lpLogBase);
std::copy(&pCharLoginOut->m_usDataSize[0],
&pCharLoginOut->m_usDataSize[DBUpdateData::MAX_UPDATE_DB],
m_usUpdateInfo);
size_t nSize = std::accumulate(&m_usUpdateInfo[0], &m_usUpdateInfo[DBUpdateData::MAX_UPDATE_DB], 0);
memcpy(m_szCharacterInfo, reinterpret_cast<const char*>(&pCharLoginOut[1]), nSize);
m_usDepositSize = pCharLoginOut->m_usDepositData;
memcpy(m_szDepositData, reinterpret_cast<const char*>(&pCharLoginOut[1]) + nSize, m_usDepositSize);
m_dwDepositMoney = pCharLoginOut->m_dwDepositMoney;
} break;
default: return false;
}
StatusUpdate();
PositionUpdate();
UpdateData(FALSE);
return true;
}
void CCharacterInfoDlg::StatusUpdate()
{
m_CharacterStatus.DeleteAllItems();
CHAR_INFOST* pCharInfoSt = reinterpret_cast<CHAR_INFOST*>(m_szCharacterInfo
+ std::accumulate(&m_usUpdateInfo[0], &m_usUpdateInfo[DBUpdateData::STATUS_UPDATE], 0));
struct tm* pTm = localtime(&m_time);
char szNameCIDTime[MAX_PATH];
_snprintf(szNameCIDTime, MAX_PATH - 1, "[ UID: %10u ][ %4d/%02d/%02d %02d:%02d:%02d ]",
m_dwUID, pTm->tm_year + 1900, pTm->tm_mon + 1, pTm->tm_mday,
pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
szNameCIDTime[MAX_PATH - 1] = 0;
SetWindowText(szNameCIDTime);
char szExp[64];
Math::Convert::Hex64ToStr(szExp, pCharInfoSt->Exp);
const int MAX_ROW = 22;
const int MAX_BUFFER = 32;
static const char szCharInfoField[MAX_ROW][MAX_BUFFER] =
{
"CID", "Name", "Sex", "Hair", "Face", "Race", "Class", "Fame", "Mileage", "Guild",
"Party", "Level", "Gold", "IP", "STR", "DEX", "CON", "INT", "WIS", "HP", "MP", "EXP"
};
std::string szMoney = GetMoneyString(pCharInfoSt->Gold);
CString nValue[MAX_ROW];
nValue[0].Format("%d", pCharInfoSt->CID); nValue[1].Format("%s", pCharInfoSt->Name);
nValue[2].Format("%d", pCharInfoSt->Sex); nValue[3].Format("%d", pCharInfoSt->Hair);
nValue[4].Format("%d", pCharInfoSt->Face); nValue[5].Format("%d", pCharInfoSt->Race);
nValue[6].Format("%d", pCharInfoSt->Class); nValue[7].Format("%d", pCharInfoSt->Fame);
nValue[8].Format("%d", pCharInfoSt->Mileage); nValue[9].Format("0x%08X", pCharInfoSt->GID);
nValue[10].Format("%d", pCharInfoSt->PID); nValue[11].Format("%d", pCharInfoSt->Level);
nValue[12].Format("%s", szMoney.c_str()); nValue[13].Format("%d", pCharInfoSt->IP);
nValue[14].Format("%d", pCharInfoSt->STR); nValue[15].Format("%d", pCharInfoSt->DEX);
nValue[16].Format("%d", pCharInfoSt->CON); nValue[17].Format("%d", pCharInfoSt->INT);
nValue[18].Format("%d", pCharInfoSt->WIS); nValue[19].Format("%d", pCharInfoSt->HP);
nValue[20].Format("%d", pCharInfoSt->MP); nValue[21].Format("0x%s", szExp);
for(int nCount = 0; nCount < MAX_ROW; ++nCount)
{
m_CharacterStatus.InsertItem(nCount, szCharInfoField[nCount]);
m_CharacterStatus.SetItemText(nCount, 1, nValue[nCount]);
}
}
void CCharacterInfoDlg::PositionUpdate()
{
CHAR_POS* pCharPos = reinterpret_cast<CHAR_POS*>(m_szCharacterInfo
+ std::accumulate(&m_usUpdateInfo[0], &m_usUpdateInfo[DBUpdateData::POSITION_UPDATE], 0));
if(sizeof(CHAR_POS) != m_usUpdateInfo[DBUpdateData::POSITION_UPDATE])
{
return;
}
m_LastPosX.Format("%f", pCharPos->LastPoint.fPointX);
m_LastPosY.Format("%f", pCharPos->LastPoint.fPointY);
m_LastPosZ.Format("%f", pCharPos->LastPoint.fPointZ);
m_SavePosX.Format("%f", pCharPos->SavePoint.fPointX);
m_SavePosY.Format("%f", pCharPos->SavePoint.fPointY);
m_SavePosZ.Format("%f", pCharPos->SavePoint.fPointZ);
}
void CCharacterInfoDlg::OnBnClickedItemInfo()
{
CItemInfoSheet sheet(GetMyINIString("STRING_FOR_LOCALIZE", "CHAR_ITEM_INFO"));
sheet.Initialize(m_szCharacterInfo, m_usUpdateInfo, m_szDepositData, m_usDepositSize, m_dwDepositMoney);
sheet.DoModal();
}
void CCharacterInfoDlg::OnBnClickedShowQuickslot()
{
CString title(GetMyINIString("STRING_FOR_LOCALIZE", "QUICK_SLOT_INFO"));
CString quickSlot;
QUICK* pCharQuickSlot = reinterpret_cast<QUICK*>(m_szCharacterInfo
+ std::accumulate(&m_usUpdateInfo[0], &m_usUpdateInfo[DBUpdateData::QUICKSLOT_UPDATE], 0));
if(sizeof(QUICK) != m_usUpdateInfo[DBUpdateData::QUICKSLOT_UPDATE])
{
MessageBox(GetMyINIString("STRING_FOR_LOCALIZE", "ERR_003"));
return;
}
for(int nIndex = 0; nIndex < QUICK::MAX_QUICK_NUM; ++nIndex)
{
quickSlot.AppendFormat("[ SLOT %2d ] ", nIndex);
if(0 == pCharQuickSlot->Slots[nIndex].wID)
{
quickSlot.AppendFormat("EMPTY SLOT");
}
else
{
switch(pCharQuickSlot->Slots[nIndex].nType)
{
case QUICKSLOT::NONE:
quickSlot.AppendFormat("Unknown Type: ");
break;
case QUICKSLOT::ITEM:
quickSlot.AppendFormat("SkillType ID: %d", pCharQuickSlot->Slots[nIndex].wID);
break;
case QUICKSLOT::SKILL:
quickSlot.AppendFormat("SkillType ID: 0x%04x LockCount: %d Level: %d",
pCharQuickSlot->Slots[nIndex].wID,
pCharQuickSlot->Slots[nIndex].nSkillLockCount,
pCharQuickSlot->Slots[nIndex].nSkillLevel);
};
}
quickSlot.AppendFormat("\r\n");
}
CInfoDlg quickInfoDlg(title, quickSlot);
quickInfoDlg.DoModal();
}
void CCharacterInfoDlg::OnBnClickedShowSkillslot()
{
CString title(GetMyINIString("STRING_FOR_LOCALIZE", "SKILL_SLOT_INFO"));
CString skillSlot;
SKILL* pCharSKILLSlot = reinterpret_cast<SKILL*>(m_szCharacterInfo
+ std::accumulate(&m_usUpdateInfo[0], &m_usUpdateInfo[DBUpdateData::SKILL_UPDATE], 0));
if(sizeof(SKILL) != m_usUpdateInfo[DBUpdateData::SKILL_UPDATE])
{
MessageBox(GetMyINIString("STRING_FOR_LOCALIZE", "ERR_004"));
return;
}
for(int nIndex = 0; nIndex < SKILL::MAX_SLOT_NUM; ++nIndex)
{
skillSlot.AppendFormat("[ SLOT %2d ] ", nIndex);
if(0 == pCharSKILLSlot->SSlot[nIndex].SKILLINFO.wSkill)
{
skillSlot.AppendFormat("EMPTY SLOT");
}
else
{
skillSlot.AppendFormat("SkillType ID: 0x%04x LockCount: %d Level: %d",
pCharSKILLSlot->SSlot[nIndex].SKILLINFO.wSkill,
pCharSKILLSlot->SSlot[nIndex].SKILLINFO.cLockCount,
pCharSKILLSlot->SSlot[nIndex].SKILLINFO.cSkillLevel);
}
skillSlot.AppendFormat("\r\n");
}
CInfoDlg skillInfoDlg(title, skillSlot);
skillInfoDlg.DoModal();
}
BOOL CCharacterInfoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_CharacterStatus.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_FLATSB);
m_CharacterStatus.InsertColumn(0, GetMyINIString("STRING_FOR_LOCALIZE", "ITEM"), LVCFMT_LEFT, 50);
m_CharacterStatus.InsertColumn(1, GetMyINIString("STRING_FOR_LOCALIZE", "VALUE"), LVCFMT_LEFT, 140);
SetDlgItemText(IDC_CHARACTERINFO_GROUP, GetMyINIString("STRING_FOR_LOCALIZE", "CHAR_INFO"));
SetDlgItemText(IDC_EXPORT_BUTTON, GetMyINIString("STRING_FOR_LOCALIZE", "SHOW_ITEM_INFO"));
SetDlgItemText(IDC_SHOW_QUICKSLOT, GetMyINIString("STRING_FOR_LOCALIZE", "SHOW_QSLOT_INFO"));
SetDlgItemText(IDC_SHOW_SKILLSLOT, GetMyINIString("STRING_FOR_LOCALIZE", "SHOW_SKILLSLOT_INFO"));
return TRUE;
}