Corrected server response when adding an item to a trade session fails. (#7462)

Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
Jittapan Pluemsumran 2022-11-29 13:24:34 +07:00 committed by GitHub
parent 4661016445
commit 4e638838de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 21 deletions

View File

@ -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<uint8>(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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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);
}