From 4e638838de1c99abbcc289d7679580cacb502b18 Mon Sep 17 00:00:00 2001 From: Jittapan Pluemsumran Date: Tue, 29 Nov 2022 13:24:34 +0700 Subject: [PATCH] Corrected server response when adding an item to a trade session fails. (#7462) Co-authored-by: Lemongrass3110 --- src/map/clif.cpp | 17 +++++++---------- src/map/clif.hpp | 10 +++++++++- src/map/packets.hpp | 7 +++++++ src/map/trade.cpp | 18 ++++++++---------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index df6d90f914..6dd1dec4cc 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -4671,17 +4671,14 @@ void clif_tradeadditem( struct map_session_data* sd, struct map_session_data* ts /// 0 = success /// 1 = overweight /// 2 = trade canceled -void clif_tradeitemok(struct map_session_data* sd, int index, int fail) +void clif_tradeitemok(struct map_session_data& sd, int index, e_exitem_add_result result) { - int fd; - nullpo_retv(sd); + PACKET_ZC_ACK_ADD_EXCHANGE_ITEM p = {}; + p.packetType = HEADER_ZC_ACK_ADD_EXCHANGE_ITEM; + p.index = client_index(index); + p.result = static_cast(result); - fd = sd->fd; - WFIFOHEAD(fd,packet_len(0xea)); - WFIFOW(fd,0) = 0xea; - WFIFOW(fd,2) = index; - WFIFOB(fd,4) = fail; - WFIFOSET(fd,packet_len(0xea)); + clif_send(&p, sizeof(p), &sd.bl, SELF); } @@ -12435,7 +12432,7 @@ void clif_parse_TradeAddItem(int fd,struct map_session_data *sd) if( index == 0 ) trade_tradeaddzeny(sd, amount); else - trade_tradeadditem(sd, index, (short)amount); + trade_tradeadditem(sd, server_index(index), (short)amount); } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index dd35c867f7..df768c92f2 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -596,6 +596,14 @@ enum e_memorial_dungeon_command : uint16 { COMMAND_MEMORIALDUNGEON_DESTROY_FORCE = 0x3, }; +enum e_exitem_add_result : uint8 { + EXITEM_ADD_SUCCEED, + EXITEM_ADD_FAILED_OVERWEIGHT, + EXITEM_ADD_FAILED_CLOSED, + EXITEM_ADD_FAILED_OVERCOUNT, + EXITEM_ADD_FAILED_EACHITEM_OVERCOUNT, +}; + int clif_setip(const char* ip); void clif_setbindip(const char* ip); void clif_setport(uint16 port); @@ -690,7 +698,7 @@ void clif_hotkeys_send(struct map_session_data *sd, int tab); void clif_traderequest(struct map_session_data* sd, const char* name); void clif_tradestart(struct map_session_data* sd, uint8 type); void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd, int index, int amount); -void clif_tradeitemok(struct map_session_data* sd, int index, int fail); +void clif_tradeitemok(struct map_session_data& sd, int index, e_exitem_add_result result); void clif_tradedeal_lock(struct map_session_data* sd, int fail); void clif_tradecancelled(struct map_session_data* sd); void clif_tradecompleted(struct map_session_data* sd, int fail); diff --git a/src/map/packets.hpp b/src/map/packets.hpp index 14c60ed2e4..d1ecb6d2a6 100644 --- a/src/map/packets.hpp +++ b/src/map/packets.hpp @@ -407,6 +407,12 @@ struct PACKET_ZC_ACK_OPEN_BANKING{ int16 unknown; } __attribute__((packed)); +struct PACKET_ZC_ACK_ADD_EXCHANGE_ITEM { + int16 packetType; + uint16 index; + uint8 result; +} __attribute__((packed)); + // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 ) #pragma pack( pop ) @@ -416,6 +422,7 @@ DEFINE_PACKET_HEADER(ZC_NOTIFY_CHAT, 0x8d) DEFINE_PACKET_HEADER(ZC_BROADCAST, 0x9a) DEFINE_PACKET_HEADER(ZC_ITEM_ENTRY, 0x9d) DEFINE_PACKET_HEADER(ZC_PC_PURCHASE_RESULT, 0xca) +DEFINE_PACKET_HEADER(ZC_ACK_ADD_EXCHANGE_ITEM, 0xea) DEFINE_PACKET_HEADER(ZC_MVP_GETTING_ITEM, 0x10a) DEFINE_PACKET_HEADER(CZ_REQ_CHANGE_MEMBERPOS, 0x155) DEFINE_PACKET_HEADER(CZ_REQMAKINGITEM, 0x18e) diff --git a/src/map/trade.cpp b/src/map/trade.cpp index 7a3efa8262..d1ff88d041 100644 --- a/src/map/trade.cpp +++ b/src/map/trade.cpp @@ -362,12 +362,10 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) } if( !amount ) { // Why do this.. ~.~ just send an ack, the item won't display on the trade window. - clif_tradeitemok(sd, index, 0); + clif_tradeitemok(*sd, -2, EXITEM_ADD_SUCCEED); // We pass -2 which will becomes 0 in clif_tradeitemok (Official behavior) return; } - index -= 2; // 0 is for zeny, 1 is unknown. Gravity, go figure... - // Item checks... if( index < 0 || index >= MAX_INVENTORY ) return; @@ -381,7 +379,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) if( !itemdb_cantrade(item, src_lv, dst_lv) && // Can't trade (pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) { // Can't partner-trade clif_displaymessage (sd->fd, msg_txt(sd,260)); - clif_tradeitemok(sd, index+2, 1); + clif_tradeitemok(*sd, index, EXITEM_ADD_FAILED_CLOSED); return; } @@ -390,13 +388,13 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) if( item->expire_time ) { // Rental System clif_displaymessage (sd->fd, msg_txt(sd,260)); - clif_tradeitemok(sd, index+2, 1); + clif_tradeitemok(*sd, index, EXITEM_ADD_FAILED_CLOSED); return; } if( ((item->bound == BOUND_ACCOUNT || item->bound > BOUND_GUILD) || (item->bound == BOUND_GUILD && sd->status.guild_id != target_sd->status.guild_id)) && !pc_can_give_bounded_items(sd) ) { // Item Bound clif_displaymessage(sd->fd, msg_txt(sd,293)); - clif_tradeitemok(sd, index+2, 1); + clif_tradeitemok(*sd, index, EXITEM_ADD_FAILED_CLOSED); return; } @@ -411,13 +409,13 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) // Locate a trade position ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 ); if( trade_i == 10 ) { // No space left - clif_tradeitemok(sd, index+2, 1); + // clif_tradeitemok(*sd, index, EXITEM_ADD_FAILED_OVERWEIGHT); // We do not know if the server respond with this or not since the official client prevents this case client-side. return; } trade_weight = sd->inventory_data[index]->weight * amount; if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight ) { // fail to add item -- the player was over weighted. - clif_tradeitemok(sd, index+2, 1); + clif_tradeitemok(*sd, index, EXITEM_ADD_FAILED_OVERWEIGHT); return; } @@ -435,7 +433,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) sd->deal.weight += trade_weight; - clif_tradeitemok(sd, index+2, 0); // Return the index as it was received + clif_tradeitemok(*sd, index, EXITEM_ADD_SUCCEED); // Return the index as it was received clif_tradeadditem(sd, target_sd, index+2, amount); } @@ -486,7 +484,7 @@ void trade_tradeok(struct map_session_data *sd) } sd->state.deal_locked = 1; - clif_tradeitemok(sd, 0, 0); + clif_tradeitemok(*sd, 0, EXITEM_ADD_SUCCEED); clif_tradedeal_lock(sd, 0); clif_tradedeal_lock(target_sd, 1); }