Batch #10386 by gordaoprogramas: 0 byte-identical, 1 confirmed by peer review. - fn_12750 UINewChatWnd::SendMsg: logic confirmed by peer review Peer-reviewed-by: dori, cremane, doczeira Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). Adds to the build: Source/UI/Chat/UINewChatWnd.cpp
652 lines
25 KiB
C++
652 lines
25 KiB
C++
#include "UI/Chat/UINewChatWnd.h"
|
|
|
|
#include "Client/Input/Mouse.h"
|
|
#include "Client/Mode/CMode.h"
|
|
#include "Client/Replay.h"
|
|
#include "Client/Session.h"
|
|
#include "Contents/Configuration/ServiceConfiguration.h"
|
|
#include "Contents/Jobs/JobInheritance.h"
|
|
#include "Contents/MessageTable.h"
|
|
#include "Network/TextEncoding.h"
|
|
#include "Render/Renderer.h"
|
|
#include "UI/Buttons/UITextButton.h"
|
|
#include "UI/Chat/UISubChatHisWnd.h"
|
|
#include "UI/Edit/UIEditCtrl.h"
|
|
#include "UI/Edit/UIItemTagCtrl.h"
|
|
#include "UI/Lists/UIChatHisBox.h"
|
|
#include "UI/Lists/UITabControl.h"
|
|
#include "UI/Text/NavigationLink.h"
|
|
#include "UI/Text/TextMarkup.h"
|
|
#include "UI/Text/TextWrapping.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "UI/Window/UIWindowMgr.h"
|
|
#include "Utility/Text/FormatString.h"
|
|
|
|
#include <windows.h>
|
|
#include <mbstring.h>
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
|
|
// OFFSET: 0x00936360
|
|
// FUNCTION: fn_12750
|
|
int UINewChatWnd::SendMsg(UIWindow* sender, int message, std::intptr_t a, std::intptr_t b, std::intptr_t c, std::intptr_t d) {
|
|
if (g_replayAnimationScaling != 0 && Replay::Instance().header.options.recordRestricted == 0) {
|
|
return 1;
|
|
}
|
|
|
|
switch (message) {
|
|
case 0x9A:
|
|
for (std::map<int, SubChatWndInfo>::iterator it = g_session.m_noSubChatWnds.begin(); it != g_session.m_noSubChatWnds.end(); ++it) {
|
|
static_cast<UIChatHisBox*>(this->m_tabs[it->first])->ResolvePlayerTags(reinterpret_cast<const char*>(a));
|
|
}
|
|
return 0;
|
|
case 0x75: {
|
|
if (!g_session.m_canDragWnd || g_session.m_noSubChatWnds.size() <= 1) {
|
|
return 0;
|
|
}
|
|
std::map<int, SubChatWndInfo>& names = g_session.m_noSubChatWnds;
|
|
std::map<int, SubChatWndInfo>::iterator found = names.find(this->m_currentTab);
|
|
if (found == names.end()) {
|
|
return 0;
|
|
}
|
|
int detached = static_cast<int>(g_session.m_subChatWnds.size());
|
|
g_session.m_subChatWnds[detached] = found->second;
|
|
const int key = found->first;
|
|
names.erase(found);
|
|
if (key != names.size()) {
|
|
std::map<int, SubChatWndInfo> saved(names);
|
|
names.clear();
|
|
int index = 0;
|
|
for (std::map<int, SubChatWndInfo>::iterator it = saved.begin(); it != saved.end(); ++it, ++index) {
|
|
names[index] = it->second;
|
|
}
|
|
}
|
|
|
|
this->m_tabControl->RemoveTab(this->m_currentTab);
|
|
this->m_tabWidth = this->m_tabControl->geometry.width / names.size();
|
|
UISubChatHisWnd* window = static_cast<UISubChatHisWnd*>(g_windowMgr.sub_A97580(static_cast<int>(g_windowMgr.retainedWindows.size()), -1, -1, 0, 0));
|
|
if (window == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
std::vector<UIChatHisBox*>::iterator tab = this->m_tabs.begin() + this->m_currentTab;
|
|
if (tab != this->m_tabs.end()) {
|
|
window->ChatBox()->CopyHistory(*static_cast<UIChatHisBox*>(*tab));
|
|
this->RemoveChild(*tab, 1);
|
|
this->m_tabs.erase(tab);
|
|
}
|
|
|
|
RECT rectangle;
|
|
rectangle.left = 3;
|
|
rectangle.top = 0;
|
|
rectangle.right = this->m_tabWidth + 3 + this->m_tabControl->geometry.width;
|
|
rectangle.bottom = this->m_tabControl->geometry.height;
|
|
this->FillSurface(0xFFFF00FF, &rectangle);
|
|
if (this->m_currentTab > 0) {
|
|
--this->m_currentTab;
|
|
this->m_tabControl->unknown_007C = this->m_currentTab;
|
|
}
|
|
this->RefreshTabs(true);
|
|
|
|
if (sender != this) {
|
|
int x = 0;
|
|
int y = 0;
|
|
this->ToScreen(x, y);
|
|
g_windowMgr.ReleaseCapture();
|
|
window->Move(x, y);
|
|
window->Slot25(g_mouse.x - this->m_tabWidth * a - x, g_mouse.y - y);
|
|
}
|
|
this->ApplyHeaderLayout();
|
|
return 0;
|
|
}
|
|
case 0x76: {
|
|
if (!g_session.m_canDragWnd || this->m_tabControl->geometry.width + this->m_tabWidth > this->geometry.width - 0x5A) {
|
|
return 0;
|
|
}
|
|
int index = static_cast<UISubChatHisWnd*>(sender)->m_index;
|
|
std::map<int, SubChatWndInfo>& windows = g_session.m_subChatWnds;
|
|
std::map<int, SubChatWndInfo>::iterator found = windows.find(index);
|
|
if (found == windows.end()) {
|
|
return 0;
|
|
}
|
|
|
|
int count = static_cast<int>(g_session.m_noSubChatWnds.size());
|
|
if (this->TextWidth(found->second.name.c_str(), 0, 0, 12, 0, 0) * (count + 1)
|
|
> this->geometry.width - 0x5A) {
|
|
g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0);
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0x6F0)), 0xFF, 0, 0, 0);
|
|
g_windowMgr.Promote(sender);
|
|
return 0;
|
|
}
|
|
|
|
g_session.m_noSubChatWnds[count] = found->second;
|
|
this->m_tabControl->AddTab(found->second.name.c_str(), "");
|
|
this->m_tabWidth = this->m_tabControl->geometry.width / g_session.m_noSubChatWnds.size();
|
|
const int key = found->first;
|
|
windows.erase(found);
|
|
if (key != windows.size()) {
|
|
std::map<int, SubChatWndInfo> saved(windows);
|
|
windows.clear();
|
|
int renumbered = 0;
|
|
for (std::map<int, SubChatWndInfo>::iterator it = saved.begin(); it != saved.end(); ++it, ++renumbered) {
|
|
windows[renumbered] = it->second;
|
|
}
|
|
}
|
|
|
|
int height = this->geometry.height - this->m_inputOffsetY - this->m_inputAreaHeight - 4;
|
|
if (height < 0) {
|
|
height = this->m_inputAreaHeight;
|
|
}
|
|
UIChatHisBox* source = static_cast<UISubChatHisWnd*>(g_windowMgr.retainedWindows[index])->ChatBox();
|
|
UIChatHisBox* box = new UIChatHisBox();
|
|
box->Configure(0, 0, this->geometry.width - 8, height, 0);
|
|
box->Move(-100 - this->geometry.width, -100);
|
|
this->AddChild(box);
|
|
box->CopyHistory(*source);
|
|
this->m_tabs.push_back(box);
|
|
g_windowMgr.ReleaseRetainedWindow(index);
|
|
if (index != g_windowMgr.retainedWindows.size()) {
|
|
std::map<int, UIWindow*> saved(g_windowMgr.retainedWindows);
|
|
g_windowMgr.retainedWindows.clear();
|
|
int renumbered = 0;
|
|
for (std::map<int, UIWindow*>::iterator it = saved.begin(); it != saved.end(); ++it, ++renumbered) {
|
|
static_cast<UISubChatHisWnd*>(it->second)->m_index = renumbered;
|
|
g_windowMgr.retainedWindows[renumbered] = it->second;
|
|
}
|
|
}
|
|
|
|
RECT rectangle;
|
|
rectangle.left = 3;
|
|
rectangle.top = 0;
|
|
rectangle.right = this->m_tabControl->geometry.width + 3;
|
|
rectangle.bottom = this->m_tabControl->geometry.height;
|
|
this->FillSurface(0xFFFF00FF, &rectangle);
|
|
this->m_currentTab = count;
|
|
this->m_tabControl->unknown_007C = count;
|
|
this->RefreshTabs(true);
|
|
this->ApplyHeaderLayout();
|
|
return 0;
|
|
}
|
|
case 0x74:
|
|
if (this->geometry.height <= this->m_inputOffsetY + this->m_inputAreaHeight) {
|
|
return 0;
|
|
}
|
|
if (sender == this->m_tabControl) {
|
|
if (a != 0) {
|
|
g_session.m_noSubChatWnds[b].name = reinterpret_cast<const char*>(a);
|
|
this->m_tabWidth = this->m_tabControl->geometry.width / g_session.m_noSubChatWnds.size();
|
|
g_windowMgr.SetFocus(this->m_inputEdit);
|
|
if (UIWindow* window = g_windowMgr.LookupWindow(0x84)) {
|
|
window->SendMsg(this, 6, 0xC1, this->m_currentTab, 1, 2);
|
|
}
|
|
}
|
|
RECT rectangle;
|
|
rectangle.left = 3;
|
|
rectangle.top = 0;
|
|
rectangle.right = (c != 0 ? c : this->m_tabControl->geometry.width) + 3;
|
|
rectangle.bottom = this->m_tabControl->geometry.height;
|
|
this->FillSurface(0xFFFF00FF, &rectangle);
|
|
this->ApplyHeaderLayout();
|
|
this->Invalidate();
|
|
return 0;
|
|
} else {
|
|
RECT rectangle;
|
|
rectangle.left = 5;
|
|
rectangle.top = this->m_inputOffsetY + 2;
|
|
rectangle.right = this->geometry.width - 6;
|
|
rectangle.bottom = this->geometry.height - this->m_inputAreaHeight - 2;
|
|
this->FillSurface(0xFFFF00FF, &rectangle);
|
|
return 0;
|
|
}
|
|
case 0x16:
|
|
if (a == this->m_currentTab) {
|
|
this->RefreshTabs(false);
|
|
} else {
|
|
this->m_currentTab = a;
|
|
this->RefreshTabs(true);
|
|
}
|
|
return 0;
|
|
case 0x46: {
|
|
std::string name(reinterpret_cast<const char*>(a));
|
|
const int count = static_cast<int>(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history.size());
|
|
int index = 0;
|
|
for (std::vector<std::string>::iterator it = static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history.begin(); it != static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history.end(); ++it, ++index) {
|
|
if (*it == name) {
|
|
UIWhisperEditCtrl* whisper = static_cast<UIWhisperEditCtrl*>(this->unknown_00C0);
|
|
whisper->history.erase(it);
|
|
if (static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex == index) {
|
|
static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex = count - 1;
|
|
} else if (static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex > index) {
|
|
static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex = static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex - 1;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
case 0x27:
|
|
switch (this->unknown_00F0) {
|
|
case 1:
|
|
*reinterpret_cast<int*>(&g_session.unknown_5490[0x8]) = a;
|
|
switch (a) {
|
|
case 0:
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->TextColor(RGB(0, 0, 0), 0xFFFFFFFF);
|
|
break;
|
|
case 1:
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->TextColor(RGB(128, 0, 128), 0xFFFFFFFF);
|
|
break;
|
|
case 2:
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->TextColor(RGB(0, 128, 128), 0xFFFFFFFF);
|
|
break;
|
|
case 4:
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->TextColor(RGB(148, 0, 211), 0xFFFFFFFF);
|
|
break;
|
|
}
|
|
this->Invalidate();
|
|
return 0;
|
|
case 0: {
|
|
const int count = static_cast<int>(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history.size());
|
|
if (a >= 0 && a <= count) {
|
|
static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->SetText(a == count ? "" : static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history[a].c_str());
|
|
static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex = a;
|
|
}
|
|
g_windowMgr.SetFocus(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0));
|
|
break;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
case 0x36:
|
|
g_windowMgr.SetFocus(static_cast<UIChatEditCtrl*>(this->m_chatEdit));
|
|
return 0;
|
|
case 0x25:
|
|
case 0x73:
|
|
if (message != 0x73) {
|
|
std::vector<std::string> lines;
|
|
char name[25] = {};
|
|
if (d != 0) {
|
|
std::strcpy(name, reinterpret_cast<const char*>(d));
|
|
}
|
|
|
|
switch (c) {
|
|
case 1:
|
|
case 3:
|
|
case 4:
|
|
case 21: {
|
|
std::string text(reinterpret_cast<const char*>(a));
|
|
const int length = static_cast<int>(std::strlen(reinterpret_cast<const char*>(a)));
|
|
const int position = static_cast<int>(text.find(" :"));
|
|
if (position > 0 && position < length && position < 24) {
|
|
std::memcpy(name, reinterpret_cast<const char*>(a), position);
|
|
name[position] = '\0';
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (g_serviceType == 10 && std::strlen(name) > 24) {
|
|
return 0;
|
|
}
|
|
|
|
if (std::strcmp(name, g_session.DecodePlayerName()) == 0) {
|
|
name[0] = '\0';
|
|
}
|
|
|
|
bool hasLink = false;
|
|
std::string plain = RemoveTextColors(reinterpret_cast<const char*>(a));
|
|
if (g_navigationLinkParser->HasLink(plain)) {
|
|
hasLink = true;
|
|
lines.push_back(plain);
|
|
} else {
|
|
WrapPlainText(
|
|
RemoveTextColors(reinterpret_cast<const char*>(a)).c_str(), lines, 0x5E
|
|
);
|
|
}
|
|
|
|
const bool everyTab = c == 25 || (c == 0 && b == 0xFF);
|
|
int index = 0;
|
|
for (std::map<int, SubChatWndInfo>::iterator it = g_session.m_noSubChatWnds.begin(); it != g_session.m_noSubChatWnds.end(); ++it, ++index) {
|
|
if ((it->second.options[c] || everyTab) && this->m_tabs[index] != nullptr) {
|
|
static_cast<UIChatHisBox*>(this->m_tabs[index])->AddLinkRecord(reinterpret_cast<const char*>(a), b, name);
|
|
for (unsigned int line = 0; line < lines.size(); ++line) {
|
|
UIWindow* tab = this->m_tabs[index];
|
|
const int width = this->TextWidth(lines[line].c_str(), 0, 0, 12, 0, 0);
|
|
if (width <= tab->geometry.width - 20 || hasLink) {
|
|
static_cast<UIChatHisBox*>(this->m_tabs[index])->AddText(lines[line].c_str(), b, name);
|
|
} else {
|
|
static_cast<UIChatHisBox*>(this->m_tabs[index])->AddTextWrapped(lines[line].c_str(), b, name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
index = 0;
|
|
for (std::map<int, SubChatWndInfo>::iterator it = g_session.m_subChatWnds.begin(); it != g_session.m_subChatWnds.end(); ++it, ++index) {
|
|
if (it->second.options[c] || everyTab) {
|
|
g_windowMgr.retainedWindows[index]->SendMsg(this, 0x25, a, b, reinterpret_cast<std::intptr_t>(name), 0);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
case 0x22:
|
|
if (g_windowMgr.unknown_0030 < 0 || g_windowMgr.unknown_0034 < 0 || g_windowMgr.unknown_0030 > g_renderer->viewport.width - this->geometry.width
|
|
|| g_windowMgr.unknown_0034 > g_renderer->viewport.height - this->geometry.height) {
|
|
g_windowMgr.unknown_0030 = 0;
|
|
g_windowMgr.unknown_0034 = g_renderer->viewport.height - this->geometry.height;
|
|
}
|
|
this->geometry.x = g_windowMgr.unknown_0030;
|
|
this->geometry.y = g_windowMgr.unknown_0034;
|
|
this->ResizeRows(g_windowMgr.unknown_004C);
|
|
this->Move(this->geometry.x, this->geometry.y);
|
|
return 0;
|
|
case 6:
|
|
switch (a) {
|
|
case 0xC1:
|
|
if (UIWindow* window = g_windowMgr.sub_A978D0(0x84)) {
|
|
window->SendMsg(this, 6, 0xC1, this->m_currentTab, 1, 0);
|
|
}
|
|
return 0;
|
|
case 0x15B:
|
|
g_windowMgr.SelectWhisperName(reinterpret_cast<const char*>(b));
|
|
return 0;
|
|
case 0x165:
|
|
*reinterpret_cast<unsigned char*>(&g_windowMgr.unknown_03F4) = 1;
|
|
this->m_currentTab = 0;
|
|
if (this->unknown_0118 == 0) {
|
|
this->unknown_0118 = 1;
|
|
}
|
|
this->ResizeRows(this->unknown_0118);
|
|
this->Invalidate();
|
|
return 0;
|
|
case 0x166:
|
|
this->SendMsg(this, 0x75, this->m_currentTab, 0, 0, 0);
|
|
return 0;
|
|
case 0xEE: {
|
|
this->unknown_00F0 = 1;
|
|
if (g_windowMgr.unknown_0214 != nullptr) {
|
|
g_windowMgr.CloseWindow(0x1A);
|
|
}
|
|
UIWindow* menu = g_windowMgr.sub_A978D0(0x1A);
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x55)), 0, 0, 0);
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x56)), 0, 0, 0);
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x1B5)), 0, 0, 0);
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0x939)), 0, 0, 0);
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(LookupMessage(0xFC0)), 0, 0, 0);
|
|
menu->SendMsg(nullptr, 0x28, *reinterpret_cast<int*>(&g_session.unknown_5490[0x8]), 0, 0, 0);
|
|
menu->Resize(0x70, 0x30);
|
|
menu->SendMsg(nullptr, 0x53, 1, 0, 0, 0);
|
|
int x = this->geometry.width - 0x73;
|
|
int y = this->geometry.height - this->m_inputAreaHeight;
|
|
this->ToScreen(x, y);
|
|
menu->Move(x + 1, y - 0x2F);
|
|
return 0;
|
|
}
|
|
case 0xE1: {
|
|
this->unknown_00F0 = 0;
|
|
if (g_windowMgr.unknown_0214 != nullptr) {
|
|
g_windowMgr.CloseWindow(0x1A);
|
|
}
|
|
const int count = static_cast<int>(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history.size());
|
|
if (count == 0) {
|
|
g_windowMgr.SendNotice(3, 0, 0, 0, 0, 0);
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0xC0)), 0xFF, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
UIWindow* menu = g_windowMgr.sub_A978D0(0x1A);
|
|
for (int i = 0; i < count; ++i) {
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->history[i].c_str()), 0, 0, 0);
|
|
}
|
|
menu->SendMsg(nullptr, 0x1F, reinterpret_cast<std::intptr_t>(""), 0, 0, 0);
|
|
int height = (count + 1) * 16;
|
|
if (height > 0x50) {
|
|
height = 0x50;
|
|
}
|
|
menu->SendMsg(nullptr, 0x28, static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->historyIndex, 0, 0, 0);
|
|
menu->Resize(0x70, height);
|
|
menu->SendMsg(nullptr, 0x53, 1, 0, 0, 0);
|
|
int x = 0;
|
|
int y = this->geometry.height - this->m_inputAreaHeight;
|
|
this->ToScreen(x, y);
|
|
menu->Move(x + 1, y - height + 1);
|
|
return 0;
|
|
}
|
|
case 0xB8: {
|
|
if (!g_windowMgr.inputSuggestionsEnabled && g_windowMgr.chatModeChanged) {
|
|
return 0;
|
|
}
|
|
|
|
char buffer[0x16A];
|
|
std::memset(buffer, 0, sizeof(buffer));
|
|
std::string text(static_cast<UIChatEditCtrl*>(this->m_chatEdit)->Text());
|
|
const std::size_t lineEnd = text.find('\n', 0);
|
|
if (lineEnd != std::string::npos) {
|
|
text = text.substr(0, lineEnd);
|
|
}
|
|
|
|
UIChatEditCtrl* edit = static_cast<UIChatEditCtrl*>(this->m_chatEdit);
|
|
bool rejected = HasItemLinkTag(std::string(edit->Text()));
|
|
if (!rejected) {
|
|
UIItemTagOnChat* tags = static_cast<UIChatEditCtrl*>(this->m_chatEdit)->unknown_0144;
|
|
if (tags != nullptr && tags->unknown_0140.size() != 0) {
|
|
text = std::string(tags->unknown_0140);
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->unknown_0144->unknown_0140.clear();
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->unknown_0144->ClearTags();
|
|
rejected = static_cast<UIChatEditCtrl*>(this->m_chatEdit)->LinkedText().size() != 0;
|
|
}
|
|
if (!rejected) {
|
|
if (static_cast<UIChatEditCtrl*>(this->m_chatEdit)->LinkedText().size() != 0) {
|
|
text = static_cast<UIChatEditCtrl*>(this->m_chatEdit)->LinkedText();
|
|
}
|
|
edit = static_cast<UIChatEditCtrl*>(this->m_chatEdit);
|
|
rejected = HasNaviLinkTag(std::string(edit->Text()));
|
|
}
|
|
}
|
|
|
|
if (rejected) {
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->SetText("");
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0xBE2)), 0xFF, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
StringFormat(buffer, sizeof(buffer), static_cast<std::size_t>(-1), "%s", text.c_str());
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->PushHistory();
|
|
this->m_inputEdit = static_cast<UIChatEditCtrl*>(this->m_chatEdit);
|
|
g_windowMgr.SetFocus(static_cast<UIChatEditCtrl*>(this->m_chatEdit));
|
|
static_cast<UIChatEditCtrl*>(this->m_chatEdit)->linkedText.clear();
|
|
if (std::strlen(buffer) == 0) {
|
|
return 0;
|
|
}
|
|
|
|
if (g_serviceType == 1 && !ValidateCharacterName(buffer)) {
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0xBE)), 0xFF, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
if (static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->Length() != 0 && buffer[0] != '/') {
|
|
g_windowMgr.unknown_04DC = buffer;
|
|
g_modeMgr.gameMode->SendMsg(0xB, reinterpret_cast<int>(static_cast<UIWhisperEditCtrl*>(this->unknown_00C0)->Text()), 0, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
if (g_session.ProcessEmotionShortcut(buffer) != 0) {
|
|
return 0;
|
|
}
|
|
|
|
std::string parts[3];
|
|
int talkType;
|
|
const int offset = g_session.GetTalkType(buffer, &talkType, parts);
|
|
if (talkType == 0x37 || talkType == 0x1A || talkType == 0x12) {
|
|
if (_mbsstr(reinterpret_cast<const unsigned char*>(buffer), reinterpret_cast<const unsigned char*>("<ITEML>")) != nullptr
|
|
|| _mbsstr(reinterpret_cast<const unsigned char*>(buffer), reinterpret_cast<const unsigned char*>("</ITEML>")) != nullptr) {
|
|
g_windowMgr.SendNotice(1, reinterpret_cast<std::intptr_t>(LookupMessage(0xAFC)), 0x64FFFF, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
}
|
|
if (offset != -1) {
|
|
g_windowMgr.SetUnknown04DC(buffer + offset);
|
|
}
|
|
g_modeMgr.gameMode->SendMsg(0x2A, talkType, reinterpret_cast<int>(parts), 0, 0);
|
|
return 0;
|
|
}
|
|
case 0xD4:
|
|
this->SendMsg(nullptr, 2, 0, 0, 0, 0);
|
|
return 0;
|
|
case 0x176: {
|
|
int noSubCount = static_cast<int>(g_session.m_noSubChatWnds.size());
|
|
int subCount = static_cast<int>(g_session.m_subChatWnds.size());
|
|
const int total = noSubCount + subCount;
|
|
if (total == this->unknown_0110) {
|
|
g_windowMgr.Confirm(LookupMessage(0x62A), 0, true, false, 0, "Message", 0x118, 0x78, 0);
|
|
return 0;
|
|
}
|
|
|
|
SubChatWndInfo info = {};
|
|
info.name = "NewTab_";
|
|
char number[16];
|
|
info.name += _itoa(total + 1, number, 10);
|
|
if ((noSubCount + 1) * this->m_tabWidth > this->geometry.width - 0x5A) {
|
|
g_session.m_subChatWnds[subCount] = info;
|
|
g_windowMgr.sub_A97580(static_cast<int>(g_windowMgr.retainedWindows.size()), -1, -1, 0, 0);
|
|
} else {
|
|
g_session.m_noSubChatWnds[noSubCount] = info;
|
|
this->m_tabControl->AddTab(info.name.c_str(), "");
|
|
this->m_tabWidth = this->m_tabControl->geometry.width / g_session.m_noSubChatWnds.size();
|
|
UIChatHisBox* box = new UIChatHisBox();
|
|
static_cast<UIChatHisBox*>(box)->Configure(0, 0, this->geometry.width - 8, this->geometry.height - this->m_inputAreaHeight - this->m_inputOffsetY - 4, 0);
|
|
box->Move(-100 - this->geometry.width, -100);
|
|
this->AddChild(box);
|
|
this->m_tabs.push_back(box);
|
|
|
|
RECT rectangle;
|
|
rectangle.left = 3;
|
|
rectangle.top = 0;
|
|
rectangle.right = this->m_tabControl->geometry.width + 3;
|
|
rectangle.bottom = this->m_tabControl->geometry.height;
|
|
this->FillSurface(0xFFFF00FF, &rectangle);
|
|
this->m_currentTab = noSubCount;
|
|
this->m_tabControl->unknown_007C = noSubCount;
|
|
this->RefreshTabs(true);
|
|
this->ApplyHeaderLayout();
|
|
}
|
|
return 0;
|
|
}
|
|
case 0xCA: {
|
|
std::map<int, SubChatWndInfo>& names = g_session.m_noSubChatWnds;
|
|
if (names.size() <= 1) {
|
|
return 0;
|
|
}
|
|
std::map<int, SubChatWndInfo>::iterator found = names.find(this->m_currentTab);
|
|
if (found == names.end()) {
|
|
return 0;
|
|
}
|
|
const int key = found->first;
|
|
names.erase(found);
|
|
if (key != names.size()) {
|
|
std::map<int, SubChatWndInfo> saved(names);
|
|
names.clear();
|
|
int index = 0;
|
|
for (std::map<int, SubChatWndInfo>::iterator it = saved.begin(); it != saved.end(); ++it, ++index) {
|
|
names[index] = it->second;
|
|
}
|
|
}
|
|
|
|
std::vector<UIChatHisBox*>::iterator tab = this->m_tabs.begin() + this->m_currentTab;
|
|
if (tab != this->m_tabs.end()) {
|
|
this->RemoveChild(*tab, 1);
|
|
this->m_tabs.erase(tab);
|
|
}
|
|
this->m_tabControl->RemoveTab(this->m_currentTab);
|
|
this->m_tabWidth = this->m_tabControl->geometry.width / names.size();
|
|
|
|
RECT rectangle;
|
|
rectangle.left = 3;
|
|
rectangle.top = 0;
|
|
rectangle.right = this->m_tabWidth + this->m_tabControl->geometry.width + 3;
|
|
rectangle.bottom = this->m_tabControl->geometry.height;
|
|
this->FillSurface(0xFFFF00FF, &rectangle);
|
|
if (this->m_currentTab > 0) {
|
|
--this->m_currentTab;
|
|
this->m_tabControl->unknown_007C = this->m_currentTab;
|
|
}
|
|
this->RefreshTabs(true);
|
|
this->ApplyHeaderLayout();
|
|
if (UIWindow* window = g_windowMgr.LookupWindow(0x84)) {
|
|
window->SendMsg(this, 6, 0xC1, this->m_currentTab, 1, 1);
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
case 0xE:
|
|
if (a == 2 && static_cast<unsigned char>(g_windowMgr.unknown_03F4) != 0) {
|
|
const int top = this->m_inputOffsetY + 0x38;
|
|
if (c < top) {
|
|
if (this->geometry.unknown_0030 != 0) {
|
|
this->ResizeRows(0);
|
|
}
|
|
} else {
|
|
int rows = (c - top) / 14 + 1;
|
|
if (rows > 15) {
|
|
rows = 15;
|
|
}
|
|
if (this->geometry.unknown_0030 != rows) {
|
|
this->ResizeRows(rows);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
case 2:
|
|
if (static_cast<unsigned char>(g_windowMgr.unknown_03F4) != 0) {
|
|
const int step = a == 0 ? 1 : -1;
|
|
int rows = step;
|
|
if (this->geometry.unknown_0030 != 0) {
|
|
rows = static_cast<int>(this->geometry.unknown_0030) + step * 3;
|
|
}
|
|
if (rows > 0) {
|
|
this->ResizeRows(rows / 3 * 3 + 1);
|
|
} else {
|
|
this->ResizeRows(this->geometry.unknown_0030 != 0 ? 0 : rows);
|
|
}
|
|
}
|
|
return 0;
|
|
case 4: {
|
|
UIListBox* tab = static_cast<UIListBox*>(this->m_tabs[this->m_currentTab]);
|
|
if (tab != nullptr && tab->verticalOverflow != 0) {
|
|
if (HIBYTE(GetKeyState(VK_CONTROL))) {
|
|
tab->SendMsg(nullptr, 7, tab->LineCount(), 0, 0, 0);
|
|
} else {
|
|
tab->SendMsg(nullptr, 10, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
case 3: {
|
|
UIListBox* tab = static_cast<UIListBox*>(this->m_tabs[this->m_currentTab]);
|
|
if (tab != nullptr && tab->verticalOverflow != 0) {
|
|
if (HIBYTE(GetKeyState(VK_CONTROL))) {
|
|
tab->SendMsg(nullptr, 7, -tab->LineCount(), 0, 0, 0);
|
|
} else {
|
|
tab->SendMsg(nullptr, 9, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
case 0xF:
|
|
this->ResizeRows(a);
|
|
return 0;
|
|
case 0x10:
|
|
if (static_cast<unsigned char>(g_windowMgr.unknown_03F4) != 0 && this->geometry.unknown_0030 == 0) {
|
|
this->ResizeRows(1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return this->UIFrameWnd::SendMsg(sender, message, a, b, c, d);
|
|
}
|