Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read extended letter packet #148

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Source Main 5.2/source/UIControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2152,7 +2152,7 @@ BOOL CUILetterListBox::RenderDataLine(int iLineNumber)

wcsncpy(Text, m_TextListIter->m_szID, MAX_TEXT_LENGTH);
g_pRenderText->RenderText(iPos_x + 4 + GetColumnPos_x(1), iPos_y, Text, GetColumnWidth(1) - 4, 0, RT3_SORT_LEFT_CLIP);
wcsncpy(Text, m_TextListIter->m_szDate + 2, MAX_TEXT_LENGTH);
wcsncpy(Text, m_TextListIter->m_szDate, MAX_TEXT_LENGTH);
g_pRenderText->RenderText(iPos_x + GetColumnPos_x(2), iPos_y, Text, GetColumnWidth(2), 0, RT3_SORT_CENTER);
int iMaxWidth = m_iWidth - m_fScrollBarWidth - GetColumnPos_x(3) - 4;
g_pRenderText->RenderText(iPos_x + 4 + GetColumnPos_x(3), iPos_y, m_TextListIter->m_szText, iMaxWidth, 0, RT3_SORT_LEFT_CLIP);
Expand Down
18 changes: 13 additions & 5 deletions Source Main 5.2/source/UIWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extern DWORD g_dwMouseUseUIID;
extern CUITextInputBox* g_pSingleTextInputBox;
extern DWORD g_dwTopWindow;
extern DWORD g_dwKeyFocusUIID;
extern void ReceiveLetterText(std::span<const BYTE> ReceiveBuffer);
extern void ReceiveLetterText(std::span<const BYTE> ReceiveBuffer, bool isCached);

int g_iLetterReadNextPos_x, g_iLetterReadNextPos_y;

Expand Down Expand Up @@ -2300,7 +2300,7 @@ void CUIPhotoViewer::SetEquipmentPacket(BYTE* pbyEquip)
//CHARACTER *c = CharactersClient;
//CharactersClient = &m_PhotoChar;

ChangeCharacterExt(0, pbyEquip, &m_PhotoChar, &m_PhotoHelper);
ReadEquipmentExtended(0, 0, pbyEquip, &m_PhotoChar, &m_PhotoHelper);

m_fPhotoHelperScale = m_PhotoHelper.Scale * 0.7f / Hero->Object.Scale;

Expand Down Expand Up @@ -3114,7 +3114,7 @@ BOOL CUILetterReadWindow::HandleMessage()
else
{
auto data = reinterpret_cast<const BYTE*>(g_pLetterList->GetLetterText(dwPrevID));
ReceiveLetterText(std::span(data, sizeof(FS_LETTER_TEXT)));
ReceiveLetterText(std::span(data, sizeof(FS_LETTER_TEXT)), true);
}
}
else
Expand Down Expand Up @@ -3155,7 +3155,7 @@ BOOL CUILetterReadWindow::HandleMessage()
else
{
auto data = reinterpret_cast<const BYTE*>(g_pLetterList->GetLetterText(dwNextID));
ReceiveLetterText(std::span(data, sizeof(FS_LETTER_TEXT)));
ReceiveLetterText(std::span(data, sizeof(FS_LETTER_TEXT)), true);
}
}
else
Expand Down Expand Up @@ -4198,12 +4198,20 @@ void CLetterList::RemoveLetterTextCache(DWORD dwIndex)
m_LetterCacheIter = m_LetterCache.find(dwIndex);
if (m_LetterCacheIter != m_LetterCache.end())
{
auto letter = &m_LetterCacheIter->second;
delete letter;
m_LetterCache.erase(m_LetterCacheIter);
}
}

void CLetterList::ClearLetterTextCache()
{
for (auto cachedLetter : m_LetterCache)
{
auto letter = &cachedLetter.second;
delete letter;
}

m_LetterCache.clear();
}

Expand Down Expand Up @@ -4429,7 +4437,7 @@ BOOL CUILetterBoxTabWindow::HandleMessage()
else
{
auto data = reinterpret_cast<const BYTE*>(g_pLetterList->GetLetterText(dwLetterID));
ReceiveLetterText(std::span(data, sizeof(FS_LETTER_TEXT)));
ReceiveLetterText(std::span(data, sizeof(FS_LETTER_TEXT)), true);
}
}
else
Expand Down
116 changes: 28 additions & 88 deletions Source Main 5.2/source/WSclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,72 +465,6 @@ void ReceiveChangePassword(const BYTE* ReceiveBuffer)
}
}

void ReceiveCharacterList(std::span<const BYTE> ReceiveBuffer)
{
InitGuildWar();

auto Data = safe_cast<PHEADER_DEFAULT_CHARACTER_LIST>(ReceiveBuffer);
if (Data == nullptr)
{
assert(false);
return;
}

int Offset = sizeof(PHEADER_DEFAULT_CHARACTER_LIST);

#ifdef _DEBUG
g_ConsoleDebug->Write(MCD_RECEIVE, L"[ReceiveList Count %d Max class %d]", Data->CharacterCount, Data->MaxClass);
#else
g_ErrorReport.Write(L"[ReceiveList Count %d Max class %d]", Data->CharacterCount, Data->MaxClass);
#endif

CharacterAttribute->IsVaultExtended = Data->IsVaultExtended;
for (int i = 0; i < Data->CharacterCount; i++)
{
auto Data2 = safe_cast<PRECEIVE_CHARACTER_LIST_EXTENDED>(ReceiveBuffer.subspan(Offset));
if (Data2 == nullptr)
{
assert(false);
return;
}

auto iClass = gCharacterManager.ChangeServerClassTypeToClientClassType(Data2->Class);

float fPos[2], fAngle = 0.0f;

switch (Data2->Index)
{
#ifdef PJH_NEW_SERVER_SELECT_MAP
case 0: fPos[0] = 8008.0f; fPos[1] = 18885.0f; fAngle = 115.0f; break;
case 1: fPos[0] = 7986.0f; fPos[1] = 19145.0f; fAngle = 90.0f; break;
case 2: fPos[0] = 8046.0f; fPos[1] = 19400.0f; fAngle = 75.0f; break;
case 3: fPos[0] = 8133.0f; fPos[1] = 19645.0f; fAngle = 60.0f; break;
case 4: fPos[0] = 8282.0f; fPos[1] = 19845.0f; fAngle = 35.0f; break;
#else //PJH_NEW_SERVER_SELECT_MAP
case 0: fPos[0] = 22628.0f; fPos[1] = 15012.0f; fAngle = 100.0f; break;
case 1: fPos[0] = 22700.0f; fPos[1] = 15201.0f; fAngle = 75.0f; break;
case 2: fPos[0] = 22840.0f; fPos[1] = 15355.0f; fAngle = 50.0f; break;
case 3: fPos[0] = 23019.0f; fPos[1] = 15443.0f; fAngle = 25.0f; break;
case 4: fPos[0] = 23211.6f; fPos[1] = 15467.0f; fAngle = 0.0f; break;
#endif //PJH_NEW_SERVER_SELECT_MAP
default: return;
}

CHARACTER* c = CreateHero(Data2->Index, iClass, 0, fPos[0], fPos[1], fAngle);

c->Level = Data2->Level;
c->CtlCode = Data2->CtlCode;

CMultiLanguage::ConvertFromUtf8(c->ID, Data2->ID, MAX_ID_SIZE);

ChangeCharacterExt(Data2->Index, Data2->Equipment);

c->GuildStatus = Data2->byGuildStatus;
Offset += sizeof(PRECEIVE_CHARACTER_LIST_EXTENDED);
}
CurrentProtocolState = RECEIVE_CHARACTERS_LIST;
}

void ReceiveCharacterListExtended(const BYTE* ReceiveBuffer)
{
InitGuildWar();
Expand Down Expand Up @@ -9589,19 +9523,17 @@ void ReceiveLetter(const BYTE* ReceiveBuffer)
{
auto Data = (LPFS_LETTER_ALERT)ReceiveBuffer;

wchar_t szDate[16] = { 0 };
CMultiLanguage::ConvertFromUtf8(szDate, Data->Name + 11, 10);
szDate[10] = '\0';
wchar_t szDate[MAX_LETTER_DATE_LENGTH + 1] = { };
CMultiLanguage::ConvertFromUtf8(szDate, Data->Date, MAX_LETTER_DATE_LENGTH);

wchar_t szTime[16] = { 0 };
CMultiLanguage::ConvertFromUtf8(szTime, Data->Name + 11, 8);
szTime[8] = '\0';
wchar_t szTime[MAX_LETTER_TIME_LENGTH + 1] = { };
CMultiLanguage::ConvertFromUtf8(szTime, Data->Time, MAX_LETTER_TIME_LENGTH);

wchar_t szName[MAX_ID_SIZE + 1] = { 0 };
wchar_t szName[MAX_ID_SIZE + 1] = { };
CMultiLanguage::ConvertFromUtf8(szName, Data->Name, MAX_ID_SIZE);
szName[MAX_ID_SIZE] = '\0';

wchar_t szSubject[MAX_TEXT_LENGTH + 1] = { 0 };
wchar_t szSubject[MAX_TEXT_LENGTH + 1] = { };
CMultiLanguage::ConvertFromUtf8(szSubject, Data->Subject, MAX_ID_SIZE);
szSubject[MAX_ID_SIZE] = '\0';

Expand Down Expand Up @@ -9633,28 +9565,34 @@ void ReceiveLetter(const BYTE* ReceiveBuffer)

extern int g_iLetterReadNextPos_x, g_iLetterReadNextPos_y;

void ReceiveLetterText(std::span<const BYTE> ReceiveBuffer)
void ReceiveLetterText(std::span<const BYTE> ReceiveBuffer, bool isCached)
{
auto Data = safe_cast<FS_LETTER_TEXT>(ReceiveBuffer);
auto Data = safe_cast<FS_LETTER_TEXT_HEADER>(ReceiveBuffer);
if (Data == nullptr)
{
assert(false);
return;
}

g_pLetterList->CacheLetterText(Data->Index, Data);
if (!isCached)
{
// Cache it if you can :)
auto CopiedData = new FS_LETTER_TEXT();
memcpy(CopiedData, ReceiveBuffer.data(), ReceiveBuffer.size());
g_pLetterList->CacheLetterText(Data->Index, CopiedData);
}

auto pLetter = g_pLetterList->GetLetter(Data->Index);
if (pLetter == nullptr)
auto pLetterHead = g_pLetterList->GetLetter(Data->Index);
if (pLetterHead == nullptr)
{
return;
}

pLetter->m_bIsRead = TRUE;
pLetterHead->m_bIsRead = TRUE;
g_pWindowMgr->RefreshMainWndLetterList();

wchar_t tempTxt[MAX_TEXT_LENGTH + 1];
swprintf(tempTxt, GlobalText[1054], pLetter->m_szText);
swprintf(tempTxt, GlobalText[1054], pLetterHead->m_szText);
DWORD dwUIID = 0;
if (g_iLetterReadNextPos_x == UIWND_DEFAULT)
{
Expand All @@ -9667,13 +9605,15 @@ void ReceiveLetterText(std::span<const BYTE> ReceiveBuffer)
}

auto* pWindow = (CUILetterReadWindow*)g_pWindowMgr->GetWindow(dwUIID);
wchar_t szText[1000 + 1] = { 0 };
CMultiLanguage::ConvertFromUtf8(szText, Data->Memo, 1000);
szText[1000] = '\0';
pWindow->SetLetter(pLetter, szText);
g_pWindowMgr->SetLetterReadWindow(pLetter->m_dwLetterID, dwUIID);
auto* pLetterText = (char*)ReceiveBuffer.subspan(sizeof(FS_LETTER_TEXT_HEADER)).data();
wchar_t letterText[1000 + 1] = { };
CMultiLanguage::ConvertFromUtf8(letterText, pLetterText, MAX_LETTERTEXT_LENGTH);
letterText[MAX_LETTERTEXT_LENGTH] = '\0';
pWindow->SetLetter(pLetterHead, letterText);

g_pWindowMgr->SetLetterReadWindow(pLetterHead->m_dwLetterID, dwUIID);

if (wcsnicmp(pLetter->m_szID, L"webzen", MAX_ID_SIZE) == 0)
if (wcsnicmp(pLetterHead->m_szID, L"webzen", MAX_ID_SIZE) == 0)
{
pWindow->m_Photo.SetWebzenMail(TRUE);
}
Expand Down Expand Up @@ -14282,7 +14222,7 @@ static void ProcessPacket(const BYTE* ReceiveBuffer, int32_t Size)
ReceiveLetter(ReceiveBuffer);
break;
case 0xC7:
ReceiveLetterText(received_span);
ReceiveLetterText(received_span, false);
break;
case 0xC8:
ReceiveLetterDeleteResult(ReceiveBuffer);
Expand Down
30 changes: 22 additions & 8 deletions Source Main 5.2/source/WSclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -1734,21 +1734,35 @@ typedef struct {
PBMSG_HEADER Header;
WORD Index;
char Name[MAX_ID_SIZE];
char Date[30];
char Date[MAX_LETTER_DATE_LENGTH];
char Separator;
char Time[MAX_LETTER_TIME_LENGTH];
char Reserved[30 - MAX_LETTER_DATE_LENGTH - MAX_LETTER_TIME_LENGTH - 1];
char Subject[MAX_LETTER_TITLE_LENGTH];
BYTE Read;
} FS_LETTER_ALERT, * LPFS_LETTER_ALERT;

typedef struct {
PWMSG_HEADER Header;
WORD Index;
WORD MemoSize;
SERVER_CLASS_TYPE Class;
WORD Index;
SERVER_CLASS_TYPE Class;
BYTE Flags;
BYTE Equipment[EQUIPMENT_LENGTH_EXTENDED];
BYTE Reserved[40 - EQUIPMENT_LENGTH_EXTENDED];
BYTE PhotoDir;
BYTE PhotoAction;
} FS_LETTER_TEXT_HEADER, * LPFS_LETTER_TEXT_HEADER;

typedef struct {
PWMSG_HEADER Header;
WORD Index;
SERVER_CLASS_TYPE Class;
BYTE Flags;
BYTE Equipment[EQUIPMENT_LENGTH_EXTENDED];
BYTE PhotoDir;
BYTE PhotoAction;
char Memo[MAX_LETTERTEXT_LENGTH];
BYTE Equipment[EQUIPMENT_LENGTH_EXTENDED];
BYTE Reserved[40 - EQUIPMENT_LENGTH_EXTENDED];
BYTE PhotoDir;
BYTE PhotoAction;
char Memo[MAX_LETTERTEXT_LENGTH];
} FS_LETTER_TEXT, * LPFS_LETTER_TEXT;

typedef struct {
Expand Down
3 changes: 3 additions & 0 deletions Source Main 5.2/source/_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ enum struct STORAGE_TYPE
#define MAX_NAMEFILTERS 500

#define MAX_LETTER_TITLE_LENGTH 60
#define MAX_LETTER_DATE_LENGTH 10
#define MAX_LETTER_TIME_LENGTH 8

#define MAX_LETTERTEXT_LENGTH 1000
#define MAX_CHATROOM_TEXT_LENGTH 150
#define MAX_LANGUAGE_NAME_LENGTH 4
Expand Down