mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-08 18:22:26 +00:00
Added server handler for OP_CharInventory .. Added rule-based option to split BulkSendInventory into parent item packets
This commit is contained in:
parent
a26227f258
commit
7fb3146a77
@ -726,6 +726,7 @@ RULE_BOOL(Inventory, EnforceAugmentWear, true, "Forces augment wear slot validat
|
|||||||
RULE_BOOL(Inventory, DeleteTransformationMold, true, "False if you want mold to last forever")
|
RULE_BOOL(Inventory, DeleteTransformationMold, true, "False if you want mold to last forever")
|
||||||
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
||||||
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
||||||
|
RULE_BOOL(Inventory, BulkSendEnMasse, false, "Sends player 'Enter World' inventory as one massive packet (true = normal behavior)")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Client)
|
RULE_CATEGORY(Client)
|
||||||
|
|||||||
@ -340,6 +340,9 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
temp_pvp = false;
|
temp_pvp = false;
|
||||||
is_client_moving = false;
|
is_client_moving = false;
|
||||||
|
|
||||||
|
m_op_charinventory_sent = 0;
|
||||||
|
m_op_charinventory_received = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GM
|
* GM
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -721,6 +721,11 @@ public:
|
|||||||
|
|
||||||
void OnDisconnect(bool hard_disconnect);
|
void OnDisconnect(bool hard_disconnect);
|
||||||
|
|
||||||
|
void IncrementOPCharInventorySent(size_t count = 1) { m_op_charinventory_sent += count; }
|
||||||
|
void IncrementOPCharInventoryReceived(size_t count = 1) { m_op_charinventory_received += count; }
|
||||||
|
size_t GetOpCharInventorySentCount() { return m_op_charinventory_sent; }
|
||||||
|
size_t GetOpCharInventoryReceivedCount() { return m_op_charinventory_received; }
|
||||||
|
|
||||||
uint16 GetSkillPoints() { return m_pp.points;}
|
uint16 GetSkillPoints() { return m_pp.points;}
|
||||||
void SetSkillPoints(int inp) { m_pp.points = inp;}
|
void SetSkillPoints(int inp) { m_pp.points = inp;}
|
||||||
|
|
||||||
@ -1626,6 +1631,9 @@ private:
|
|||||||
|
|
||||||
int client_max_level;
|
int client_max_level;
|
||||||
|
|
||||||
|
size_t m_op_charinventory_sent;
|
||||||
|
size_t m_op_charinventory_received;
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -89,6 +89,7 @@ void MapOpcodes()
|
|||||||
// connecting opcode handler assignments:
|
// connecting opcode handler assignments:
|
||||||
ConnectingOpcodes[OP_ApproveZone] = &Client::Handle_Connect_OP_ApproveZone;
|
ConnectingOpcodes[OP_ApproveZone] = &Client::Handle_Connect_OP_ApproveZone;
|
||||||
ConnectingOpcodes[OP_BlockedBuffs] = &Client::Handle_OP_BlockedBuffs;
|
ConnectingOpcodes[OP_BlockedBuffs] = &Client::Handle_OP_BlockedBuffs;
|
||||||
|
ConnectingOpcodes[OP_CharInventory] = &Client::Handle_Connect_OP_CharInventory;
|
||||||
ConnectingOpcodes[OP_ClientError] = &Client::Handle_Connect_OP_ClientError;
|
ConnectingOpcodes[OP_ClientError] = &Client::Handle_Connect_OP_ClientError;
|
||||||
ConnectingOpcodes[OP_ClientReady] = &Client::Handle_Connect_OP_ClientReady;
|
ConnectingOpcodes[OP_ClientReady] = &Client::Handle_Connect_OP_ClientReady;
|
||||||
ConnectingOpcodes[OP_ClientUpdate] = &Client::Handle_Connect_OP_ClientUpdate;
|
ConnectingOpcodes[OP_ClientUpdate] = &Client::Handle_Connect_OP_ClientUpdate;
|
||||||
@ -932,6 +933,41 @@ void Client::Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Handle_Connect_OP_CharInventory(const EQApplicationPacket* app)
|
||||||
|
{
|
||||||
|
if (ClientVersionBit() & EQEmu::versions::maskRoFAndLater) {
|
||||||
|
|
||||||
|
IncrementOPCharInventoryReceived();
|
||||||
|
if (GetOpCharInventorySentCount() == GetOpCharInventoryReceivedCount()) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Weather Packet
|
||||||
|
This shouldent be moved, this seems to be what the client
|
||||||
|
uses to advance to the next state (sending ReqNewZone)
|
||||||
|
*/
|
||||||
|
auto outapp = new EQApplicationPacket(OP_Weather, 12);
|
||||||
|
Weather_Struct* ws = (Weather_Struct*)outapp->pBuffer;
|
||||||
|
ws->val1 = 0x000000FF;
|
||||||
|
if (zone->zone_weather == 1) {
|
||||||
|
ws->type = 0x31; // Rain
|
||||||
|
}
|
||||||
|
if (zone->zone_weather == 2) {
|
||||||
|
|
||||||
|
outapp->pBuffer[8] = 0x01;
|
||||||
|
ws->type = 0x02;
|
||||||
|
}
|
||||||
|
outapp->priority = 6;
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
Handle_Connect_OP_ReqNewZone(nullptr);
|
||||||
|
SetAttackTimer();
|
||||||
|
conn_state = ZoneInfoSent;
|
||||||
|
zoneinpacket_timer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Handle_Connect_OP_ClientError(const EQApplicationPacket *app)
|
void Client::Handle_Connect_OP_ClientError(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (app->size != sizeof(ClientError_Struct)) {
|
if (app->size != sizeof(ClientError_Struct)) {
|
||||||
@ -1655,15 +1691,20 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
this is not quite where live sends inventory, they do it after tribute
|
this is not quite where live sends inventory, they do it after tribute
|
||||||
*/
|
*/
|
||||||
if (loaditems) { /* Dont load if a length error occurs */
|
if (loaditems) { /* Dont load if a length error occurs */
|
||||||
if (admin >= minStatusToBeGM)
|
|
||||||
|
if (admin >= minStatusToBeGM) {
|
||||||
m_inv.SetGMInventory(true); // set to true to allow expansion-restricted packets through
|
m_inv.SetGMInventory(true); // set to true to allow expansion-restricted packets through
|
||||||
|
}
|
||||||
|
|
||||||
BulkSendInventoryItems();
|
BulkSendInventoryItems();
|
||||||
|
|
||||||
/* Send stuff on the cursor which isnt sent in bulk */
|
/* Send stuff on the cursor which isnt sent in bulk */
|
||||||
for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) {
|
for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) {
|
||||||
|
|
||||||
/* First item cursor is sent in bulk inventory packet */
|
/* First item cursor is sent in bulk inventory packet */
|
||||||
if (iter == m_inv.cursor_cbegin())
|
if (iter == m_inv.cursor_cbegin()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
const EQEmu::ItemInstance *inst = *iter;
|
const EQEmu::ItemInstance *inst = *iter;
|
||||||
SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo);
|
SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo);
|
||||||
}
|
}
|
||||||
@ -1692,15 +1733,19 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ClientVersionBit() & EQEmu::versions::maskUFAndEarlier) { // RoF+ moved to Client::Handle_Connect_OP_CharInventory(...)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Weather Packet
|
Weather Packet
|
||||||
This shouldent be moved, this seems to be what the client
|
This shouldent be moved, this seems to be what the client
|
||||||
uses to advance to the next state (sending ReqNewZone)
|
uses to advance to the next state (sending ReqNewZone)
|
||||||
*/
|
*/
|
||||||
outapp = new EQApplicationPacket(OP_Weather, 12);
|
outapp = new EQApplicationPacket(OP_Weather, 12);
|
||||||
Weather_Struct *ws = (Weather_Struct *)outapp->pBuffer;
|
Weather_Struct* ws = (Weather_Struct*)outapp->pBuffer;
|
||||||
ws->val1 = 0x000000FF;
|
ws->val1 = 0x000000FF;
|
||||||
if (zone->zone_weather == 1) { ws->type = 0x31; } // Rain
|
if (zone->zone_weather == 1) {
|
||||||
|
ws->type = 0x31; // Rain
|
||||||
|
}
|
||||||
if (zone->zone_weather == 2) {
|
if (zone->zone_weather == 2) {
|
||||||
outapp->pBuffer[8] = 0x01;
|
outapp->pBuffer[8] = 0x01;
|
||||||
ws->type = 0x02;
|
ws->type = 0x02;
|
||||||
@ -1709,14 +1754,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF) {
|
|
||||||
Handle_Connect_OP_ReqNewZone(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
conn_state = ZoneInfoSent;
|
conn_state = ZoneInfoSent;
|
||||||
zoneinpacket_timer.Start();
|
zoneinpacket_timer.Start();
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// connected opcode handlers
|
// connected opcode handlers
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/* Connecting OpCode Handlers */
|
/* Connecting OpCode Handlers */
|
||||||
void Handle_Connect_0x3e33(const EQApplicationPacket *app);
|
void Handle_Connect_0x3e33(const EQApplicationPacket *app);
|
||||||
void Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app);
|
void Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app);
|
||||||
|
void Handle_Connect_OP_CharInventory(const EQApplicationPacket *app);
|
||||||
void Handle_Connect_OP_ClientError(const EQApplicationPacket *app);
|
void Handle_Connect_OP_ClientError(const EQApplicationPacket *app);
|
||||||
void Handle_Connect_OP_ClientReady(const EQApplicationPacket *app);
|
void Handle_Connect_OP_ClientReady(const EQApplicationPacket *app);
|
||||||
void Handle_Connect_OP_ClientUpdate(const EQApplicationPacket *app);
|
void Handle_Connect_OP_ClientUpdate(const EQApplicationPacket *app);
|
||||||
|
|||||||
@ -731,75 +731,86 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
|||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends the client complete inventory used in character login
|
// Sends the client complete inventory used in character login (enter world/zoning)
|
||||||
void Client::BulkSendInventoryItems()
|
void Client::BulkSendInventoryItems()
|
||||||
{
|
{
|
||||||
// LINKDEAD TRADE ITEMS
|
// Move any residual trade slot items back into normal inventory..need them there now for the proceeding validity checks
|
||||||
// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks
|
for (int16 slot_id = EQEmu::invslot::TRADE_BEGIN; slot_id <= EQEmu::invslot::TRADE_END; ++slot_id) {
|
||||||
for (int16 slot_id = EQEmu::invslot::TRADE_BEGIN; slot_id <= EQEmu::invslot::TRADE_END; slot_id++) {
|
|
||||||
EQEmu::ItemInstance* inst = m_inv.PopItem(slot_id);
|
EQEmu::ItemInstance* inst = m_inv.PopItem(slot_id);
|
||||||
if(inst) {
|
if(inst) {
|
||||||
bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
|
|
||||||
|
bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow);
|
||||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
|
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
|
||||||
LogInventory("Incomplete Trade Transaction: Moving [{}] from slot [{}] to [{}]", inst->GetItem()->Name, slot_id, free_slot_id);
|
LogInventory(
|
||||||
|
"Incomplete Trade Transaction: Moving [{}] from slot [{}] to [{}]",
|
||||||
|
inst->GetItem()->Name,
|
||||||
|
slot_id,
|
||||||
|
free_slot_id
|
||||||
|
);
|
||||||
PutItemInInventory(free_slot_id, *inst, false);
|
PutItemInInventory(free_slot_id, *inst, false);
|
||||||
database.SaveInventory(character_id, nullptr, slot_id);
|
database.SaveInventory(character_id, nullptr, slot_id);
|
||||||
safe_delete(inst);
|
safe_delete(inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deletenorent = database.NoRentExpired(GetName());
|
// Client was offline for more than 30 minutes, delete no rent items
|
||||||
if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
|
bool delete_no_rent = database.NoRentExpired(GetName());
|
||||||
if (RuleB(Inventory, TransformSummonedBags))
|
if (delete_no_rent) {
|
||||||
|
|
||||||
|
if (RuleB(Inventory, TransformSummonedBags)) {
|
||||||
DisenchantSummonedBags(false);
|
DisenchantSummonedBags(false);
|
||||||
|
}
|
||||||
RemoveNoRent(false);
|
RemoveNoRent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveDuplicateLore(false);
|
RemoveDuplicateLore(false);
|
||||||
MoveSlotNotAllowed(false);
|
MoveSlotNotAllowed(false);
|
||||||
|
|
||||||
|
if (RuleB(Inventory, BulkSendEnMasse)) { // Default behavior
|
||||||
|
|
||||||
EQEmu::OutBuffer ob;
|
EQEmu::OutBuffer ob;
|
||||||
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
||||||
|
|
||||||
// Possessions items
|
for (int16 slot_id = EQEmu::invslot::POSSESSIONS_BEGIN; slot_id <= EQEmu::invslot::POSSESSIONS_END; ++slot_id) {
|
||||||
for (int16 slot_id = EQEmu::invslot::POSSESSIONS_BEGIN; slot_id <= EQEmu::invslot::POSSESSIONS_END; slot_id++) {
|
|
||||||
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||||
if (!inst)
|
if (!inst) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
inst->Serialize(ob, slot_id);
|
inst->Serialize(ob, slot_id);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
if (ob.tellp() == last_pos)
|
|
||||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||||
|
}
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bank items
|
for (int16 slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
|
||||||
for (int16 slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; slot_id++) {
|
|
||||||
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||||
if (!inst)
|
if (!inst) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
inst->Serialize(ob, slot_id);
|
inst->Serialize(ob, slot_id);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
if (ob.tellp() == last_pos)
|
|
||||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||||
|
}
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SharedBank items
|
for (int16 slot_id = EQEmu::invslot::SHARED_BANK_BEGIN; slot_id <= EQEmu::invslot::SHARED_BANK_END; ++slot_id) {
|
||||||
for (int16 slot_id = EQEmu::invslot::SHARED_BANK_BEGIN; slot_id <= EQEmu::invslot::SHARED_BANK_END; slot_id++) {
|
|
||||||
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||||
if (!inst)
|
if (!inst) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
inst->Serialize(ob, slot_id);
|
inst->Serialize(ob, slot_id);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
if (ob.tellp() == last_pos)
|
|
||||||
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||||
|
}
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,6 +819,97 @@ void Client::BulkSendInventoryItems()
|
|||||||
outapp->pBuffer = ob.detach();
|
outapp->pBuffer = ob.detach();
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
if (ClientVersionBit() & EQEmu::versions::maskRoFAndLater) {
|
||||||
|
IncrementOPCharInventorySent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // Specialized behavior
|
||||||
|
|
||||||
|
for (int16 slot_id = EQEmu::invslot::POSSESSIONS_BEGIN; slot_id <= EQEmu::invslot::POSSESSIONS_END; ++slot_id) {
|
||||||
|
|
||||||
|
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||||
|
if (!inst) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EQEmu::OutBuffer ob;
|
||||||
|
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
||||||
|
|
||||||
|
inst->Serialize(ob, slot_id);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
|
|
||||||
|
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_CharInventory);
|
||||||
|
outapp->size = ob.size();
|
||||||
|
outapp->pBuffer = ob.detach();
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
if (ClientVersionBit() & EQEmu::versions::maskRoFAndLater) {
|
||||||
|
IncrementOPCharInventorySent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int16 slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
|
||||||
|
|
||||||
|
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||||
|
if (!inst) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EQEmu::OutBuffer ob;
|
||||||
|
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
||||||
|
|
||||||
|
inst->Serialize(ob, slot_id);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
|
|
||||||
|
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_CharInventory);
|
||||||
|
outapp->size = ob.size();
|
||||||
|
outapp->pBuffer = ob.detach();
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
if (ClientVersionBit() & EQEmu::versions::maskRoFAndLater) {
|
||||||
|
IncrementOPCharInventorySent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int16 slot_id = EQEmu::invslot::SHARED_BANK_BEGIN; slot_id <= EQEmu::invslot::SHARED_BANK_END; ++slot_id) {
|
||||||
|
|
||||||
|
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||||
|
if (!inst) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EQEmu::OutBuffer ob;
|
||||||
|
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
||||||
|
|
||||||
|
inst->Serialize(ob, slot_id);
|
||||||
|
if (ob.tellp() == last_pos) {
|
||||||
|
|
||||||
|
LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto outapp = new EQApplicationPacket(OP_CharInventory);
|
||||||
|
outapp->size = ob.size();
|
||||||
|
outapp->pBuffer = ob.detach();
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
if (ClientVersionBit() & EQEmu::versions::maskRoFAndLater) {
|
||||||
|
IncrementOPCharInventorySent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user