diff --git a/changelog.txt b/changelog.txt index 9172332d9..98e1f0606 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 08/26/2014 == +Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions. +Note: QueryServ logs previously listed 'Items' on the main entry table. This indicated the number of slots affected and not the actual number of items. +This field now indicates the actual number of items transferred. For non-stackable, the value is '1' and stackable is the number of charges. A _detail_count +property has been added to both 'Trade' and 'Handin' structs to indicate the number of details recorded..though, not tracked..it could be added. + == 08/24/2014 == Uleat: Fix (attempted) for zone crashes related to zone shut-down. This change disables all Mob AI and disables/deletes all Mob timers once Zone::ShutDown() is called. More areas will be addressed as reports come in. Note: Perl and Lua quests tested to work..please post any aberrant behavior. (I finally set my spell-check to US English...) diff --git a/common/servertalk.h b/common/servertalk.h index 6d1a83a84..5337b6b1d 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -1118,6 +1118,7 @@ struct QSPlayerLogTrade_Struct { uint32 char2_id; MoneyUpdate_Struct char2_money; uint16 char2_count; + uint16 _detail_count; QSTradeItems_Struct items[0]; }; @@ -1141,6 +1142,7 @@ struct QSPlayerLogHandin_Struct { uint32 npc_id; MoneyUpdate_Struct npc_money; uint16 npc_count; + uint16 _detail_count; QSHandinItems_Struct items[0]; }; diff --git a/queryserv/database.cpp b/queryserv/database.cpp index 4b94f215b..cfc4a8892 100644 --- a/queryserv/database.cpp +++ b/queryserv/database.cpp @@ -119,7 +119,7 @@ void Database::AddSpeech(const char* from, const char* to, const char* message, safe_delete_array(S3); } -void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) { +void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; @@ -134,8 +134,8 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) { _log(QUERYSERV__ERROR, "%s", query); } - if(Items > 0) { - for(int i = 0; i < Items; i++) { + if(DetailCount > 0) { + for(int i = 0; i < DetailCount; i++) { if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_trade_record_entries` SET `event_id`='%i', " "`from_id`='%i', `from_slot`='%i', `to_id`='%i', `to_slot`='%i', `item_id`='%i', " "`charges`='%i', `aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'", @@ -149,7 +149,7 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) { } } -void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) { +void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; uint32 lastid = 0; @@ -163,8 +163,8 @@ void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) { _log(QUERYSERV__ERROR, "%s", query); } - if(Items > 0) { - for(int i = 0; i < Items; i++) { + if(DetailCount > 0) { + for(int i = 0; i < DetailCount; i++) { if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_handin_record_entries` SET `event_id`='%i', " "`action_type`='%s', `char_slot`='%i', `item_id`='%i', `charges`='%i', " "`aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'", diff --git a/queryserv/database.h b/queryserv/database.h index ac002a0b5..a25d91611 100644 --- a/queryserv/database.h +++ b/queryserv/database.h @@ -43,8 +43,8 @@ public: ~Database(); void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type); - void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items); - void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items); + void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount); + void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount); void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members); void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items); void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items); diff --git a/queryserv/worldserver.cpp b/queryserv/worldserver.cpp index 154db3a07..fc87929ca 100644 --- a/queryserv/worldserver.cpp +++ b/queryserv/worldserver.cpp @@ -80,14 +80,12 @@ void WorldServer::Process() } case ServerOP_QSPlayerLogTrades: { QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer; - uint32 Items = QS->char1_count + QS->char2_count; - database.LogPlayerTrade(QS, Items); + database.LogPlayerTrade(QS, QS->_detail_count); break; } case ServerOP_QSPlayerLogHandins: { QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer; - uint32 Items = QS->char_count + QS->npc_count; - database.LogPlayerHandin(QS, Items); + database.LogPlayerHandin(QS, QS->_detail_count); break; } case ServerOP_QSPlayerLogNPCKills: { diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8d39f815a..76c873711 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4898,8 +4898,9 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) this->FinishTrade(other, true, &event_entry, &event_details); other->FinishTrade(this, false, &event_entry, &event_details); - ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_details.size())); + event_entry._detail_count = event_details.size(); + ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_entry._detail_count)); QSPlayerLogTrade_Struct* qs_buf = (QSPlayerLogTrade_Struct*)qs_pack->pBuffer; memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogTrade_Struct)); @@ -4951,8 +4952,9 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) FinishTrade(with->CastToNPC(), false, &event_entry, &event_details); - ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_details.size())); + event_entry._detail_count = event_details.size(); + ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_entry._detail_count)); QSPlayerLogHandin_Struct* qs_buf = (QSPlayerLogHandin_Struct*)qs_pack->pBuffer; memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogHandin_Struct)); diff --git a/zone/trading.cpp b/zone/trading.cpp index 88b277651..23d8d77af 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -656,6 +656,8 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st if (!bias_inst || (bias_inst->GetID() != inst->GetID()) || (bias_inst->GetCharges() >= bias_inst->GetItem()->StackSize)) continue; + int16 old_charges = inst->GetCharges(); + if ((bias_inst->GetCharges() + inst->GetCharges()) > bias_inst->GetItem()->StackSize) { int16 new_charges = (bias_inst->GetCharges() + inst->GetCharges()) - bias_inst->GetItem()->StackSize; @@ -667,6 +669,24 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st inst->SetCharges(0); } + if (qs_log) { + QSTradeItems_Struct* detail = new QSTradeItems_Struct; + + detail->from_id = this->character_id; + detail->from_slot = trade_slot; + detail->to_id = this->character_id; + detail->to_slot = bias_slot; + detail->item_id = inst->GetID(); + detail->charges = (old_charges - inst->GetCharges()); + detail->aug_1 = 0; + detail->aug_2 = 0; + detail->aug_3 = 0; + detail->aug_4 = 0; + detail->aug_5 = 0; + + event_details->push_back(detail); + } + if (inst->GetCharges() == 0) { DeleteItemInInventory(trade_slot); break;