Decompile 6 functions in Source/Client/Mode/GameModePackets.cpp, Source/Client/Session.cpp, ...
Batch #5691 by Yommy: 0 byte-identical, 6 confirmed by peer review. - fn_21710 CGameMode::ReceiveItem1738EquipList: logic confirmed by peer review - fn_21711 CGameMode::ReceiveItem1738EquipListOptions: logic confirmed by peer review - fn_21712 CGameMode::ReceiveItem1738NormalList: logic confirmed by peer review - fn_21713 CGameMode::ReceiveHomunculusProperty64: logic confirmed by peer review - fn_21714 CGameMode::ReceiveHomunculusProperty: logic confirmed by peer review - fn_23515 CSession::RefreshHomunculusInfo: logic confirmed by peer review Peer-reviewed-by: ragnarok-clanker, willerthal, Millenium, SapitoSucio, Lumen, superintelligence Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
parent
5f1fbc6d00
commit
dde9e6d72c
6 changed files with 283 additions and 3 deletions
|
|
@ -115,6 +115,11 @@ public:
|
|||
void ReceiveActorSequenceDeadline(const unsigned char* packet);
|
||||
void ReceiveActorSignal(const unsigned char* packet);
|
||||
void IgnorePacket(const unsigned char* packet);
|
||||
void ReceiveItem1738EquipList(const unsigned char* packet);
|
||||
void ReceiveItem1738EquipListOptions(const unsigned char* packet);
|
||||
void ReceiveItem1738NormalList(const unsigned char* packet);
|
||||
void ReceiveHomunculusProperty64(const unsigned char* packet);
|
||||
void ReceiveHomunculusProperty(const unsigned char* packet);
|
||||
void ReceiveHuntingList(const unsigned char* packet);
|
||||
void ReceiveEquipAck(const unsigned char* packet);
|
||||
void ReceiveToggleNotice(const unsigned char* packet);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@
|
|||
#include "Contents/PlayerNameDictionary.h"
|
||||
#include "Contents/World/World.h"
|
||||
#include "Network/TextEncoding.h"
|
||||
#include "UI/Item/UIItemStoreWnd.h"
|
||||
#include "UI/Text/UIStaticText.h"
|
||||
#include "UI/UIBarGraph.h"
|
||||
#include "UI/Window/UIHomunInfoWnd.h"
|
||||
#include "UI/Window/UIWindowMgr.h"
|
||||
#include "Utility/Text/FormatString.h"
|
||||
|
||||
|
|
@ -30,6 +34,10 @@ struct SessionMessengerContext {
|
|||
void UpdateRandomStats();
|
||||
};
|
||||
|
||||
struct ClientItemLists {
|
||||
bool AddItem1738(const ITEM_INFO& item, unsigned char refresh);
|
||||
};
|
||||
|
||||
namespace {
|
||||
#pragma pack(push, 1)
|
||||
struct SimulationPacketHeader {
|
||||
|
|
@ -71,8 +79,89 @@ namespace {
|
|||
/* 000F */ unsigned char unknown_000F[4];
|
||||
/* 0013 */ char name[1];
|
||||
};
|
||||
|
||||
struct ItemStoreListHeader {
|
||||
/* 0000 */ std::uint16_t packetType;
|
||||
/* 0002 */ std::uint16_t length;
|
||||
/* 0004 */ char title[24];
|
||||
};
|
||||
|
||||
struct StoreItemOption {
|
||||
/* 0000 */ std::int16_t id;
|
||||
/* 0002 */ std::int16_t value;
|
||||
/* 0004 */ unsigned char param;
|
||||
};
|
||||
|
||||
struct StoreEquipRecord {
|
||||
/* 0000 */ std::int16_t index;
|
||||
/* 0002 */ int itemId;
|
||||
/* 0006 */ unsigned char type;
|
||||
/* 0007 */ std::uint32_t location;
|
||||
/* 000B */ std::uint32_t wearState;
|
||||
/* 000F */ unsigned char refine;
|
||||
/* 0010 */ std::uint32_t cards[4];
|
||||
/* 0020 */ std::uint32_t expireTime;
|
||||
/* 0024 */ std::uint16_t bindOnEquip;
|
||||
/* 0026 */ std::uint16_t sprite;
|
||||
/* 0028 */ unsigned char flags;
|
||||
};
|
||||
|
||||
struct StoreEquipOptionRecord {
|
||||
/* 0000 */ std::int16_t index;
|
||||
/* 0002 */ int itemId;
|
||||
/* 0006 */ unsigned char type;
|
||||
/* 0007 */ std::uint32_t location;
|
||||
/* 000B */ std::uint32_t wearState;
|
||||
/* 000F */ unsigned char refine;
|
||||
/* 0010 */ std::uint32_t cards[4];
|
||||
/* 0020 */ std::uint32_t expireTime;
|
||||
/* 0024 */ std::uint16_t bindOnEquip;
|
||||
/* 0026 */ std::uint16_t sprite;
|
||||
/* 0028 */ unsigned char optionCount;
|
||||
/* 0029 */ StoreItemOption options[5];
|
||||
/* 0042 */ unsigned char flags;
|
||||
};
|
||||
|
||||
struct StoreNormalRecord {
|
||||
/* 0000 */ std::int16_t index;
|
||||
/* 0002 */ int itemId;
|
||||
/* 0006 */ unsigned char type;
|
||||
/* 0007 */ std::int16_t amount;
|
||||
/* 0009 */ std::uint32_t location;
|
||||
/* 000D */ std::uint32_t cards[4];
|
||||
/* 001D */ std::uint32_t expireTime;
|
||||
/* 0021 */ unsigned char flags;
|
||||
};
|
||||
|
||||
struct HomunculusProperty64Packet {
|
||||
/* 0000 */ std::uint16_t packetType;
|
||||
/* 0002 */ std::uint16_t type;
|
||||
/* 0004 */ std::int64_t value;
|
||||
};
|
||||
|
||||
struct HomunculusPropertyPacket {
|
||||
/* 0000 */ std::uint16_t packetType;
|
||||
/* 0002 */ std::uint16_t type;
|
||||
/* 0004 */ int value;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static_assert(sizeof(ItemStoreListHeader) == 0x1C);
|
||||
static_assert(sizeof(StoreEquipRecord) == 0x29);
|
||||
static_assert(sizeof(StoreEquipOptionRecord) == 0x43);
|
||||
static_assert(sizeof(StoreNormalRecord) == 0x22);
|
||||
|
||||
// INLINED
|
||||
int CountStoreItemOptions(const StoreItemOption* options) {
|
||||
int count = 0;
|
||||
for (int index = 0; index < 5; ++index) {
|
||||
if (options[index].id != 0) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static_assert(sizeof(SimulationPacketHeader) == 0x24);
|
||||
static_assert(sizeof(EnchantSimulationRecord) == 0x1C);
|
||||
static_assert(sizeof(PackageSimulationRecord) == 0x32);
|
||||
|
|
@ -208,6 +297,168 @@ void CGameMode::ReceiveActorSignal(const unsigned char* packet) {
|
|||
void CGameMode::IgnorePacket(const unsigned char*) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D2B710
|
||||
// FUNCTION: fn_21710
|
||||
void CGameMode::ReceiveItem1738EquipList(const unsigned char* data) {
|
||||
const ItemStoreListHeader* packet = reinterpret_cast<const ItemStoreListHeader*>(data);
|
||||
UIItemStoreWnd* window = static_cast<UIItemStoreWnd*>(g_windowMgr.EnsureWindow(33));
|
||||
if (packet->title[0] != '\0') {
|
||||
std::string title(packet->title);
|
||||
window->title->SetTextFitted(title.c_str());
|
||||
}
|
||||
|
||||
const int count = (packet->length - sizeof(ItemStoreListHeader)) / sizeof(StoreEquipRecord);
|
||||
const StoreEquipRecord* record = reinterpret_cast<const StoreEquipRecord*>(data + sizeof(ItemStoreListHeader));
|
||||
for (int i = 0; i < count; ++i, ++record) {
|
||||
StoreItemOption options[5] = {};
|
||||
ITEM_INFO item;
|
||||
item.unknown_0000[0] = record->type;
|
||||
item.unknown_0000[1] = record->index;
|
||||
item.unknown_0000[2] = record->location;
|
||||
item.unknown_0000[3] = record->wearState;
|
||||
item.quantity = 1;
|
||||
std::memcpy(item.unknown_001C, record->cards, sizeof(record->cards));
|
||||
item.SetItemId(record->itemId);
|
||||
item.identified = record->flags & 1;
|
||||
item.unknown_005D = (record->flags >> 1) & 1;
|
||||
item.unknown_0060 = record->refine;
|
||||
item.unknown_0068 = record->expireTime;
|
||||
item.unknown_0064 = record->bindOnEquip;
|
||||
*reinterpret_cast<std::uint32_t*>(item.unknown_0074) = record->sprite;
|
||||
*reinterpret_cast<unsigned char*>(item.unknown_0078) = (record->flags >> 2) & 1;
|
||||
item.unknown_0098 = CountStoreItemOptions(options);
|
||||
for (int index = 0; index < item.unknown_0098; ++index) {
|
||||
reinterpret_cast<StoreItemOption*>(item.unknown_009C)[index] = options[index];
|
||||
}
|
||||
reinterpret_cast<ClientItemLists*>(&g_session)->AddItem1738(item, 1);
|
||||
}
|
||||
|
||||
g_session.RefreshItem1738Window();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D2BA50
|
||||
// FUNCTION: fn_21711
|
||||
void CGameMode::ReceiveItem1738EquipListOptions(const unsigned char* data) {
|
||||
const ItemStoreListHeader* packet = reinterpret_cast<const ItemStoreListHeader*>(data);
|
||||
UIItemStoreWnd* window = static_cast<UIItemStoreWnd*>(g_windowMgr.EnsureWindow(33));
|
||||
if (packet->title[0] != '\0') {
|
||||
std::string title(packet->title);
|
||||
window->title->SetTextFitted(title.c_str());
|
||||
}
|
||||
|
||||
const int count = (packet->length - sizeof(ItemStoreListHeader)) / sizeof(StoreEquipOptionRecord);
|
||||
const StoreEquipOptionRecord* record = reinterpret_cast<const StoreEquipOptionRecord*>(data + sizeof(ItemStoreListHeader));
|
||||
for (int i = 0; i < count; ++i, ++record) {
|
||||
StoreItemOption options[5];
|
||||
std::memcpy(options, record->options, sizeof(options));
|
||||
ITEM_INFO item;
|
||||
item.unknown_0000[0] = record->type;
|
||||
item.unknown_0000[1] = record->index;
|
||||
item.unknown_0000[2] = record->location;
|
||||
item.unknown_0000[3] = record->wearState;
|
||||
item.quantity = 1;
|
||||
std::memcpy(item.unknown_001C, record->cards, sizeof(record->cards));
|
||||
item.SetItemId(record->itemId);
|
||||
item.identified = record->flags & 1;
|
||||
item.unknown_005D = (record->flags >> 1) & 1;
|
||||
item.unknown_0060 = record->refine;
|
||||
item.unknown_0068 = record->expireTime;
|
||||
item.unknown_0064 = record->bindOnEquip;
|
||||
*reinterpret_cast<std::uint32_t*>(item.unknown_0074) = record->sprite;
|
||||
*reinterpret_cast<unsigned char*>(item.unknown_0078) = (record->flags >> 2) & 1;
|
||||
item.unknown_0098 = CountStoreItemOptions(options);
|
||||
for (int index = 0; index < item.unknown_0098; ++index) {
|
||||
reinterpret_cast<StoreItemOption*>(item.unknown_009C)[index] = options[index];
|
||||
}
|
||||
reinterpret_cast<ClientItemLists*>(&g_session)->AddItem1738(item, 1);
|
||||
}
|
||||
|
||||
g_session.RefreshItem1738Window();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D2BDF0
|
||||
// FUNCTION: fn_21712
|
||||
void CGameMode::ReceiveItem1738NormalList(const unsigned char* data) {
|
||||
const ItemStoreListHeader* packet = reinterpret_cast<const ItemStoreListHeader*>(data);
|
||||
UIItemStoreWnd* window = static_cast<UIItemStoreWnd*>(g_windowMgr.EnsureWindow(33));
|
||||
if (packet->title[0] != '\0') {
|
||||
std::string title(packet->title);
|
||||
window->title->SetTextFitted(title.c_str());
|
||||
}
|
||||
|
||||
const int count = (packet->length - sizeof(ItemStoreListHeader)) / sizeof(StoreNormalRecord);
|
||||
const StoreNormalRecord* record = reinterpret_cast<const StoreNormalRecord*>(data + sizeof(ItemStoreListHeader));
|
||||
for (int i = 0; i < count; ++i, ++record) {
|
||||
ITEM_INFO item;
|
||||
item.unknown_0000[0] = record->type;
|
||||
item.unknown_0000[1] = record->index;
|
||||
item.unknown_0000[3] = record->location;
|
||||
item.unknown_0000[2] = 0;
|
||||
item.quantity = record->amount;
|
||||
std::memcpy(item.unknown_001C, record->cards, sizeof(record->cards));
|
||||
item.SetItemId(record->itemId);
|
||||
item.identified = record->flags & 1;
|
||||
item.unknown_005D = 0;
|
||||
item.unknown_0060 = 0;
|
||||
item.unknown_0068 = record->expireTime;
|
||||
item.unknown_0074[0] = (record->flags >> 1) & 1;
|
||||
reinterpret_cast<ClientItemLists*>(&g_session)->AddItem1738(item, 0);
|
||||
}
|
||||
|
||||
g_session.RefreshItem1738Window();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D2C190
|
||||
// FUNCTION: fn_21713
|
||||
void CGameMode::ReceiveHomunculusProperty64(const unsigned char* data) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const HomunculusProperty64Packet* packet = reinterpret_cast<const HomunculusProperty64Packet*>(data);
|
||||
switch (packet->type) {
|
||||
case 1:
|
||||
g_session.m_homunExp = packet->value;
|
||||
g_session.RefreshHomunculusInfo();
|
||||
if (UIHomunInfoWnd* window = static_cast<UIHomunInfoWnd*>(g_windowMgr.window_03C0)) {
|
||||
window->expBar->SetValues(g_session.m_homunExp, g_session.m_homunMaxExp);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
g_session.m_homunHp = static_cast<int>(packet->value);
|
||||
g_session.RefreshHomunculusInfo();
|
||||
break;
|
||||
case 7:
|
||||
g_session.m_homunSp = static_cast<int>(packet->value);
|
||||
g_session.RefreshHomunculusInfo();
|
||||
break;
|
||||
}
|
||||
|
||||
g_session.RefreshHomunculusInfo();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D2C250
|
||||
// FUNCTION: fn_21714
|
||||
void CGameMode::ReceiveHomunculusProperty(const unsigned char* data) {
|
||||
const HomunculusPropertyPacket* packet = reinterpret_cast<const HomunculusPropertyPacket*>(data);
|
||||
switch (packet->type) {
|
||||
case 5:
|
||||
g_session.m_homunHp = packet->value;
|
||||
g_session.RefreshHomunculusInfo();
|
||||
break;
|
||||
case 7:
|
||||
g_session.m_homunSp = packet->value;
|
||||
g_session.RefreshHomunculusInfo();
|
||||
break;
|
||||
case 1:
|
||||
g_session.m_homunExp = packet->value;
|
||||
g_session.RefreshHomunculusInfo();
|
||||
break;
|
||||
}
|
||||
|
||||
g_session.RefreshHomunculusInfo();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D2C2B0
|
||||
// FUNCTION: fn_21715
|
||||
void CGameMode::ReceiveHuntingList(const unsigned char* packet) {
|
||||
|
|
|
|||
|
|
@ -1681,6 +1681,15 @@ void CSession::RefreshHpSpWindows() {
|
|||
static_cast<CGameMode*>(g_modeMgr.GetGameMode())->NotifyItemBounds();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00DF9460
|
||||
// FUNCTION: fn_23515
|
||||
void CSession::RefreshHomunculusInfo() {
|
||||
if (g_modeMgr.GetGameMode() && g_windowMgr.window_03C0) {
|
||||
g_windowMgr.window_03C0->Invalidate();
|
||||
g_windowMgr.window_03C0->InvalidateChildren();
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00DFC0B0
|
||||
// FUNCTION: fn_23593
|
||||
void CSession::FlagInventoryItem(std::uint32_t id) {
|
||||
|
|
|
|||
|
|
@ -271,7 +271,14 @@ public:
|
|||
/* 556C */ int unknown_556C;
|
||||
/* 5570 */ unsigned char unknown_5570[0x4C];
|
||||
/* 55BC */ int m_homunJob;
|
||||
/* 55C0 */ unsigned char unknown_55C0[0x58];
|
||||
/* 55C0 */ unsigned char unknown_55C0[0x04];
|
||||
/* 55C4 */ int m_homunHp;
|
||||
/* 55C8 */ unsigned char unknown_55C8[0x04];
|
||||
/* 55CC */ int m_homunSp;
|
||||
/* 55D0 */ unsigned char unknown_55D0[0x10];
|
||||
/* 55E0 */ std::int64_t m_homunExp;
|
||||
/* 55E8 */ std::int64_t m_homunMaxExp;
|
||||
/* 55F0 */ unsigned char unknown_55F0[0x28];
|
||||
/* 5618 */ int m_traceAi;
|
||||
/* 561C */ int m_homunActionState;
|
||||
/* 5620 */ unsigned char unknown_5620[0xC];
|
||||
|
|
@ -706,6 +713,7 @@ public:
|
|||
void UpdateUnknown1708(int enabled);
|
||||
void RefreshItem1738Window();
|
||||
void RefreshHpSpWindows();
|
||||
void RefreshHomunculusInfo();
|
||||
void EraseRecord0734(int id);
|
||||
void IgnoreText(std::string text);
|
||||
void SaveMiniPartyInfo();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <cstddef>
|
||||
|
||||
class UICheckBox;
|
||||
class UIStaticText;
|
||||
|
||||
class UIItemStoreWnd : public UIItemBaseWnd {
|
||||
public:
|
||||
|
|
@ -21,7 +22,9 @@ public:
|
|||
/* 00F8 */ unsigned char unknown_00F8[0x08];
|
||||
/* 0100 */ UICheckBox* tabs[8];
|
||||
/* 0120 */ int unknown_0120[8];
|
||||
/* 0140 */ unsigned char unknown_0140[0x24];
|
||||
/* 0140 */ unsigned char unknown_0140[0x1C];
|
||||
/* 015C */ UIStaticText* title;
|
||||
/* 0160 */ unsigned char unknown_0160[0x04];
|
||||
/* 0164 */ WindowPlacement* saved;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,15 @@
|
|||
#include "UI/Window/UIFrameWnd.h"
|
||||
#include "Contents/UserData/NormalItemSlots.h"
|
||||
|
||||
class UIINT64BarGraph;
|
||||
|
||||
class UIHomunInfoWnd : public UIFrameWnd {
|
||||
public:
|
||||
void Slot11() override;
|
||||
|
||||
/* 00B4 */ unsigned char unknown_00B4[0x18];
|
||||
/* 00B4 */ unsigned char unknown_00B4[0x10];
|
||||
/* 00C4 */ UIINT64BarGraph* expBar;
|
||||
/* 00C8 */ unsigned char unknown_00C8[0x04];
|
||||
/* 00CC */ HomunInfoWndInfo* saved;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue