mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 01:01:30 +00:00
Fix for losing 2nd and 3rd cursor items after zoning
This commit is contained in:
parent
da121137e5
commit
1d0a6bdc71
@ -1,5 +1,8 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 09/05/2014 ==
|
||||
Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!)
|
||||
|
||||
== 09/03/2014 ==
|
||||
Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor.
|
||||
demonstar55: Added work around command to show numhits on your buffs (#shownumhits)
|
||||
|
||||
@ -143,19 +143,22 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
||||
|
||||
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end)
|
||||
{
|
||||
iter_queue it;
|
||||
int i;
|
||||
bool ret=true;
|
||||
iter_queue it;
|
||||
int i;
|
||||
bool ret = true;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
// Delete cursor items
|
||||
if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid=%i AND ( (slotid >=8000 and slotid<=8999) or slotid=%i or (slotid>=%i and slotid<=%i))", char_id, MainCursor,EmuConstants::CURSOR_BAG_BEGIN,EmuConstants::CURSOR_BAG_END), errbuf))) {
|
||||
for(it=start,i=8000;it!=end;++it,i++) {
|
||||
ItemInst *inst=*it;
|
||||
if (!(ret=SaveInventory(char_id,inst,(i==8000) ? MainCursor : i)))
|
||||
if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid = %i AND ((slotid >= 8000 AND slotid <= 8999) OR slotid = %i OR (slotid >= %i AND slotid <= %i))",
|
||||
char_id, MainCursor, EmuConstants::CURSOR_BAG_BEGIN, EmuConstants::CURSOR_BAG_END), errbuf))) {
|
||||
|
||||
for (it = start, i = 8000; it != end; ++it, i++) {
|
||||
ItemInst *inst = *it;
|
||||
if (!(ret = SaveInventory(char_id, inst, (i == 8000) ? MainCursor : i)))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
std::cout << "Clearing cursor failed: " << errbuf << std::endl;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
@ -836,8 +836,6 @@ void Client::BulkSendInventoryItems() {
|
||||
}
|
||||
}
|
||||
|
||||
// Where are cursor buffer items processed? They need to be validated as well... -U
|
||||
|
||||
bool deletenorent = database.NoRentExpired(GetName());
|
||||
if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items
|
||||
|
||||
|
||||
@ -2002,11 +2002,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
|
||||
}
|
||||
|
||||
void Client::RemoveNoRent(bool client_update) {
|
||||
int16 slot_id = 0;
|
||||
|
||||
int16 slot_id;
|
||||
|
||||
// personal
|
||||
for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) {
|
||||
// equipment
|
||||
for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if(inst && !inst->GetItem()->NoRent) {
|
||||
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
@ -2014,11 +2013,22 @@ void Client::RemoveNoRent(bool client_update) {
|
||||
}
|
||||
}
|
||||
|
||||
// general
|
||||
for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) {
|
||||
const ItemInst* inst = m_inv[slot_id];
|
||||
if (inst && !inst->GetItem()->NoRent) {
|
||||
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
DeleteItemInInventory(slot_id, 0, client_update);
|
||||
}
|
||||
}
|
||||
|
||||
// power source
|
||||
const ItemInst* inst = m_inv[MainPowerSource];
|
||||
if(inst && !inst->GetItem()->NoRent) {
|
||||
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource);
|
||||
DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent
|
||||
if (m_inv[MainPowerSource]) {
|
||||
const ItemInst* inst = m_inv[MainPowerSource];
|
||||
if (inst && !inst->GetItem()->NoRent) {
|
||||
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource);
|
||||
DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent
|
||||
}
|
||||
}
|
||||
|
||||
// containers
|
||||
@ -2065,15 +2075,41 @@ void Client::RemoveNoRent(bool client_update) {
|
||||
DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Shared Bank Container slots
|
||||
}
|
||||
}
|
||||
|
||||
// cursor & limbo
|
||||
if (!m_inv.CursorEmpty()) {
|
||||
std::list<ItemInst*> local;
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
while (!m_inv.CursorEmpty()) {
|
||||
inst = m_inv.PopItem(MainCursor);
|
||||
if (inst)
|
||||
local.push_back(inst);
|
||||
}
|
||||
|
||||
std::list<ItemInst*>::iterator iter = local.begin();
|
||||
while (iter != local.end()) {
|
||||
inst = *iter;
|
||||
if (!inst->GetItem()->NoRent)
|
||||
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from `Limbo`", inst->GetItem()->Name);
|
||||
else
|
||||
m_inv.PushCursor(**iter);
|
||||
|
||||
safe_delete(*iter);
|
||||
iter = local.erase(iter);
|
||||
}
|
||||
|
||||
database.SaveCursor(this->character_id, m_inv.cursor_begin(), m_inv.cursor_end());
|
||||
local.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Two new methods to alleviate perpetual login desyncs
|
||||
void Client::RemoveDuplicateLore(bool client_update) {
|
||||
// Split-charge stacking may be added at some point -U
|
||||
int16 slot_id;
|
||||
int16 slot_id = 0;
|
||||
|
||||
// personal
|
||||
for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) {
|
||||
// equipment
|
||||
for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) {
|
||||
ItemInst* inst = m_inv.PopItem(slot_id);
|
||||
if(inst) {
|
||||
if(CheckLoreConflict(inst->GetItem())) {
|
||||
@ -2087,17 +2123,34 @@ void Client::RemoveDuplicateLore(bool client_update) {
|
||||
}
|
||||
}
|
||||
|
||||
// general
|
||||
for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) {
|
||||
ItemInst* inst = m_inv.PopItem(slot_id);
|
||||
if (inst) {
|
||||
if (CheckLoreConflict(inst->GetItem())) {
|
||||
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
database.SaveInventory(character_id, nullptr, slot_id);
|
||||
}
|
||||
else {
|
||||
m_inv.PutItem(slot_id, *inst);
|
||||
}
|
||||
safe_delete(inst);
|
||||
}
|
||||
}
|
||||
|
||||
// power source
|
||||
ItemInst* inst = m_inv.PopItem(MainPowerSource);
|
||||
if(inst) {
|
||||
if(CheckLoreConflict(inst->GetItem())) {
|
||||
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
database.SaveInventory(character_id, nullptr, MainPowerSource);
|
||||
if (m_inv[MainPowerSource]) {
|
||||
ItemInst* inst = m_inv.PopItem(MainPowerSource);
|
||||
if (inst) {
|
||||
if (CheckLoreConflict(inst->GetItem())) {
|
||||
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
database.SaveInventory(character_id, nullptr, MainPowerSource);
|
||||
}
|
||||
else {
|
||||
m_inv.PutItem(MainPowerSource, *inst);
|
||||
}
|
||||
safe_delete(inst);
|
||||
}
|
||||
else {
|
||||
m_inv.PutItem(MainPowerSource, *inst);
|
||||
}
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
// containers
|
||||
@ -2146,11 +2199,55 @@ void Client::RemoveDuplicateLore(bool client_update) {
|
||||
}
|
||||
|
||||
// Shared Bank and Shared Bank Containers are not checked due to their allowing duplicate lore items -U
|
||||
|
||||
// cursor & limbo
|
||||
if (!m_inv.CursorEmpty()) {
|
||||
std::list<ItemInst*> local;
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
while (!m_inv.CursorEmpty()) {
|
||||
inst = m_inv.PopItem(MainCursor);
|
||||
if (inst)
|
||||
local.push_back(inst);
|
||||
}
|
||||
|
||||
std::list<ItemInst*>::iterator iter = local.begin();
|
||||
while (iter != local.end()) {
|
||||
inst = *iter;
|
||||
if (CheckLoreConflict(inst->GetItem())) {
|
||||
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name);
|
||||
safe_delete(*iter);
|
||||
iter = local.erase(iter);
|
||||
}
|
||||
else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
iter = local.begin();
|
||||
while (iter != local.end()) {
|
||||
inst = *iter;
|
||||
if (!inst->GetItem()->LoreFlag ||
|
||||
((inst->GetItem()->LoreGroup == -1) && (m_inv.HasItem(inst->GetID(), 0, invWhereCursor) == INVALID_INDEX)) ||
|
||||
(inst->GetItem()->LoreGroup && ~inst->GetItem()->LoreGroup && (m_inv.HasItemByLoreGroup(inst->GetItem()->LoreGroup, invWhereCursor) == INVALID_INDEX))) {
|
||||
|
||||
m_inv.PushCursor(**iter);
|
||||
}
|
||||
else {
|
||||
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name);
|
||||
}
|
||||
|
||||
safe_delete(*iter);
|
||||
iter = local.erase(iter);
|
||||
}
|
||||
|
||||
database.SaveCursor(this->character_id, m_inv.cursor_begin(), m_inv.cursor_end());
|
||||
local.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::MoveSlotNotAllowed(bool client_update) {
|
||||
|
||||
int16 slot_id;
|
||||
int16 slot_id = 0;
|
||||
|
||||
// equipment
|
||||
for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user