Fix #269 - Support for Player Inspection /inspection command of Equipment and Appearance Items

This commit is contained in:
Emagi 2022-08-17 13:00:08 -04:00
parent 57cd568e69
commit d01cf3e2cf
4 changed files with 87 additions and 12 deletions

View file

@ -2548,7 +2548,7 @@ PacketStruct* Item::PrepareItem(int16 version, bool merchant_item, bool loot_ite
PacketStruct* packet = 0;
if(loot_item && version > 546)
packet = configReader.getStruct("WS_LootItemGeneric", version);
else{
else{
int8 tmpType = generic_info.item_type;
if (version <= 283 && generic_info.item_type > ITEM_TYPE_RECIPE)
tmpType = 0;

View file

@ -9226,14 +9226,23 @@ void Client::InspectPlayer(Player* player_to_inspect) {
for (size_t i = 0; i < biography.length(); i++)
packet->setArrayDataByName("biography_char", biography[i], i);
LogWrite(MISC__TODO, 0, "TODO", "Why is inspect player weapons commented out? in func: %s, line: %i", __FUNCTION__, __LINE__);
/*Item* pw = player_to_inspect->GetEquipmentList()->GetItem(0);
if (pw)
packet->setItemByName("primary", pw, player_to_inspect, 0);
Item* sw = player_to_inspect->GetEquipmentList()->GetItem(1);
if (sw)
packet->setItemByName("secondary", sw, player_to_inspect, 0);*/
//DumpPacket(packet->serialize());
for(int32 s=0;s<NUM_SLOTS;s++) {
int32 slot = s*2;
char item_slot_name[64], item_slot_name_appearance[64];
_snprintf(item_slot_name,64,"slot_%u",slot);
int32 slot_appearance = (s*2)+1;
_snprintf(item_slot_name_appearance,64,"slot_%u",slot_appearance);
Item* pw = player_to_inspect->GetEquipmentList()->GetItem(s);
packet->setItemByName(item_slot_name, pw, this->GetPlayer(), 0, 13);
if(s <= EQ2_FEET_SLOT || s == EQ2_RANGE_SLOT || s == EQ2_CLOAK_SLOT) {
pw = player_to_inspect->GetAppearanceEquipmentList()->GetItem(s);
packet->setItemByName(item_slot_name_appearance, pw, this->GetPlayer(), 0, 13);
}
else {
packet->setItemByName(item_slot_name_appearance, nullptr, this->GetPlayer(), 0, 13);
}
}
QueuePacket(packet->serialize());
safe_delete(packet);
}

View file

@ -2553,6 +2553,17 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
if (!ds)
return;
uchar* ptr = (uchar*)GetStructPointer(ds);
if(!item) {
if(offset > 12) {
// for player inspection this will offset the parts of the packet that have no items
uchar bogusItemBuffer[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00 /*0x68 was item flags*/,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
int sizeOfArray = sizeof(bogusItemBuffer) / sizeof(bogusItemBuffer[0]);
ds->SetItemSize(sizeOfArray);
memcpy(ptr, bogusItemBuffer, sizeOfArray);
}
return;
}
PacketStruct* packet = item->PrepareItem(client_version, false, loot_item);
if (packet) {
int16 item_version = GetItemPacketType(packet->GetVersion());
@ -2560,6 +2571,11 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
string* generic_string_data = packet->serializeString();
int32 size = generic_string_data->length();
int32 actual_length = size;
if(offset > 12) {
size += 6; // end padding for the specialized item (used for player inspection)
}
//DumpPacket((uchar*)generic_string_data->c_str(), size);
if (size <= 13)
{
@ -2570,8 +2586,9 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
if (client_version > 546 && item->IsBag() == false && item->IsBauble() == false && item->IsFood() == false && (offset == 0 || offset == -1 || offset == 2))
size = (size * 2) - 5;
uchar* out_data = new uchar[size + 1];
memset(out_data, 0, size+1);
uchar* out_ptr = out_data;
memcpy(out_ptr, (uchar*)generic_string_data->c_str() + (9 + offset), generic_string_data->length() - (9 + offset));
memcpy(out_ptr, (uchar*)generic_string_data->c_str() + (9 + offset), actual_length - (9 + offset));
//DumpPacket((uchar*)generic_string_data->c_str() + (9 + offset), size);
//without these it will prompt for your character name
if (offset == 0 || offset == -1 || offset == 2) {

View file

@ -15405,8 +15405,57 @@ to zero and treated like placeholders." />
<Data ElementName="biography_array" Type="Array" ArraySizeVariable="num_chars">
<Data ElementName="biography_char" Type="char" />
</Data>
<Data ElementName="unknown14" Type="int8" Size="1" />
<Data ElementName="unknown_name" Type="EQ2_8Bit_String" />
<Data ElementName="unknown14" Type="int8" Size="6" />
<Data ElementName="slot_0" Type="EQ2_Item" />
<Data ElementName="slot_1" Type="EQ2_Item" />
<Data ElementName="slot_2" Type="EQ2_Item" />
<Data ElementName="slot_3" Type="EQ2_Item" />
<Data ElementName="slot_4" Type="EQ2_Item" />
<Data ElementName="slot_5" Type="EQ2_Item" />
<Data ElementName="slot_6" Type="EQ2_Item" />
<Data ElementName="slot_7" Type="EQ2_Item" />
<Data ElementName="slot_8" Type="EQ2_Item" />
<Data ElementName="slot_9" Type="EQ2_Item" />
<Data ElementName="slot_10" Type="EQ2_Item" />
<Data ElementName="slot_11" Type="EQ2_Item" />
<Data ElementName="slot_12" Type="EQ2_Item" />
<Data ElementName="slot_13" Type="EQ2_Item" />
<Data ElementName="slot_14" Type="EQ2_Item" />
<Data ElementName="slot_15" Type="EQ2_Item" />
<Data ElementName="slot_16" Type="EQ2_Item" />
<Data ElementName="slot_17" Type="EQ2_Item" />
<Data ElementName="slot_18" Type="EQ2_Item" />
<Data ElementName="slot_19" Type="EQ2_Item" />
<Data ElementName="slot_20" Type="EQ2_Item" />
<Data ElementName="slot_21" Type="EQ2_Item" />
<Data ElementName="slot_22" Type="EQ2_Item" />
<Data ElementName="slot_23" Type="EQ2_Item" />
<Data ElementName="slot_24" Type="EQ2_Item" />
<Data ElementName="slot_25" Type="EQ2_Item" />
<Data ElementName="slot_26" Type="EQ2_Item" />
<Data ElementName="slot_27" Type="EQ2_Item" />
<Data ElementName="slot_28" Type="EQ2_Item" />
<Data ElementName="slot_29" Type="EQ2_Item" />
<Data ElementName="slot_30" Type="EQ2_Item" />
<Data ElementName="slot_31" Type="EQ2_Item" />
<Data ElementName="slot_32" Type="EQ2_Item" />
<Data ElementName="slot_33" Type="EQ2_Item" />
<Data ElementName="slot_34" Type="EQ2_Item" />
<Data ElementName="slot_35" Type="EQ2_Item" />
<Data ElementName="slot_36" Type="EQ2_Item" />
<Data ElementName="slot_37" Type="EQ2_Item" />
<Data ElementName="slot_38" Type="EQ2_Item" />
<Data ElementName="slot_39" Type="EQ2_Item" />
<Data ElementName="slot_40" Type="EQ2_Item" />
<Data ElementName="slot_41" Type="EQ2_Item" />
<Data ElementName="slot_42" Type="EQ2_Item" />
<Data ElementName="slot_43" Type="EQ2_Item" />
<Data ElementName="slot_44" Type="EQ2_Item" />
<Data ElementName="slot_45" Type="EQ2_Item" />
<Data ElementName="slot_46" Type="EQ2_Item" />
<Data ElementName="slot_47" Type="EQ2_Item" />
<Data ElementName="slot_48" Type="EQ2_Item" />
<Data ElementName="slot_49" Type="EQ2_Item" /> <!-- Item.h potential max slot number, NUM_SLOTS(24) * 2 + 1 = 49 -->
<!-- <Data ElementName="equipment_start" Type="int8" Size="5810" />
<Data ElementName="Achievement_size" Type="int32" Size="1" /> -->
</Struct>