Cleaned up CZ_PC_SELL_ITEMLIST and its related functions
* Added a validation check for remaining item amount
This commit is contained in:
@@ -12295,16 +12295,15 @@ void clif_npc_sell_result(struct map_session_data* sd, unsigned char result)
|
||||
void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
|
||||
{
|
||||
int fail=0,n;
|
||||
unsigned short *item_list;
|
||||
struct s_packet_db* info = &packet_db[RFIFOW(fd,0)];
|
||||
PACKET_CZ_PC_SELL_ITEMLIST* p = reinterpret_cast<PACKET_CZ_PC_SELL_ITEMLIST*>(RFIFOP(fd, 0));
|
||||
|
||||
n = (RFIFOW(fd,info->pos[0])-4) /4; // (pktlen-(cmd+len))/listsize
|
||||
item_list = (unsigned short*)RFIFOP(fd,info->pos[1]);
|
||||
|
||||
n = (p->packetLength - 4) / sizeof(PACKET_CZ_PC_SELL_ITEMLIST_sub); // (pktlen-(cmd+len))/listsize
|
||||
|
||||
if (sd->state.trading || !sd->npc_shopid)
|
||||
fail = 1;
|
||||
else
|
||||
fail = npc_selllist(sd,n,item_list);
|
||||
fail = npc_selllist(sd, n, p->sellList);
|
||||
|
||||
sd->npc_shopid = 0; //Clear shop data.
|
||||
clif_npc_sell_result(sd, fail);
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
packet(0x00c6,-1);
|
||||
packet(0x00c7,-1);
|
||||
parseable_packet(0x00c8,-1,clif_parse_NpcBuyListSend,2,4);
|
||||
parseable_packet(0x00c9,-1,clif_parse_NpcSellListSend,2,4);
|
||||
parseable_packet(HEADER_CZ_PC_SELL_ITEMLIST,-1,clif_parse_NpcSellListSend,2,4);
|
||||
packet(0x00ca,3);
|
||||
packet(0x00cb,3);
|
||||
parseable_packet(0x00cc,6,clif_parse_GMKick,2);
|
||||
|
||||
@@ -2849,7 +2849,7 @@ e_purchase_result npc_buylist( struct map_session_data* sd, std::vector<s_npc_bu
|
||||
}
|
||||
|
||||
/// npc_selllist for script-controlled shops
|
||||
static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd)
|
||||
static int npc_selllist_sub(struct map_session_data* sd, int list_length, PACKET_CZ_PC_SELL_ITEMLIST_sub* item_list, struct npc_data* nd)
|
||||
{
|
||||
char npc_ev[EVENT_NAME_LENGTH];
|
||||
char card_slot[NAME_LENGTH];
|
||||
@@ -2891,12 +2891,12 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
|
||||
}
|
||||
|
||||
// save list of to be sold items
|
||||
for( i = 0; i < n; i++ )
|
||||
for( i = 0; i < list_length; i++ )
|
||||
{
|
||||
int idx = item_list[i * 2] - 2;
|
||||
int idx = item_list[i].index - 2;
|
||||
|
||||
script_setarray_pc( sd, "@sold_nameid", i, sd->inventory.u.items_inventory[idx].nameid, &key_nameid );
|
||||
script_setarray_pc( sd, "@sold_quantity", i, item_list[i*2+1], &key_amount );
|
||||
script_setarray_pc( sd, "@sold_quantity", i, item_list[i].amount, &key_amount );
|
||||
|
||||
if( itemdb_isequip(sd->inventory.u.items_inventory[idx].nameid) )
|
||||
{// process equipment based information into the arrays
|
||||
@@ -2933,7 +2933,7 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
|
||||
///
|
||||
/// @param item_list 'n' pairs <index,amount>
|
||||
/// @return result code for clif_parse_NpcSellListSend
|
||||
uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list)
|
||||
uint8 npc_selllist(struct map_session_data* sd, int list_length, PACKET_CZ_PC_SELL_ITEMLIST_sub* item_list)
|
||||
{
|
||||
double z;
|
||||
int i,skill;
|
||||
@@ -2950,13 +2950,13 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list
|
||||
z = 0;
|
||||
|
||||
// verify the sell list
|
||||
for( i = 0; i < n; i++ )
|
||||
for( i = 0; i < list_length; i++ )
|
||||
{
|
||||
t_itemid nameid;
|
||||
int amount, idx, value;
|
||||
|
||||
idx = item_list[i*2]-2;
|
||||
amount = item_list[i*2+1];
|
||||
idx = item_list[i].index - 2;
|
||||
amount = item_list[i].amount;
|
||||
|
||||
if( idx >= MAX_INVENTORY || idx < 0 || amount < 0 )
|
||||
{
|
||||
@@ -2965,7 +2965,7 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list
|
||||
|
||||
nameid = sd->inventory.u.items_inventory[idx].nameid;
|
||||
|
||||
if( !nameid || !sd->inventory_data[idx] || sd->inventory.u.items_inventory[idx].amount < amount )
|
||||
if( !nameid || !sd->inventory_data[idx] || sd->inventory.u.items_inventory[idx].amount < amount)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -2989,16 +2989,16 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list
|
||||
|
||||
if( nd->master_nd )
|
||||
{// Script-controlled shops
|
||||
return npc_selllist_sub(sd, n, item_list, nd->master_nd);
|
||||
return npc_selllist_sub(sd, list_length, item_list, nd->master_nd);
|
||||
}
|
||||
|
||||
// delete items
|
||||
for( i = 0; i < n; i++ )
|
||||
for( i = 0; i < list_length; i++ )
|
||||
{
|
||||
int amount, idx;
|
||||
|
||||
idx = item_list[i*2]-2;
|
||||
amount = item_list[i*2+1];
|
||||
idx = item_list[i].index - 2;
|
||||
amount = item_list[i].amount;
|
||||
|
||||
// Forged packet, we do not care if he loses items
|
||||
if( sd->inventory_data[idx] == nullptr ){
|
||||
@@ -3013,7 +3013,9 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list
|
||||
}
|
||||
}
|
||||
|
||||
pc_delitem(sd, idx, amount, 0, 6, LOG_TYPE_NPC);
|
||||
if (pc_delitem(sd, idx, amount, 0, 6, LOG_TYPE_NPC)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( z > MAX_ZENY )
|
||||
|
||||
@@ -1488,7 +1488,7 @@ struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* b
|
||||
int npc_buysellsel(struct map_session_data* sd, int id, int type);
|
||||
e_purchase_result npc_buylist(struct map_session_data* sd, std::vector<s_npc_buy_list>& item_list);
|
||||
static int npc_buylist_sub(struct map_session_data* sd, std::vector<s_npc_buy_list>& item_list, struct npc_data* nd);
|
||||
uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list);
|
||||
uint8 npc_selllist(struct map_session_data* sd, int list_length, PACKET_CZ_PC_SELL_ITEMLIST_sub* item_list);
|
||||
e_purchase_result npc_barter_purchase( struct map_session_data& sd, std::shared_ptr<s_npc_barter> barter, std::vector<s_barter_purchase>& purchases );
|
||||
void npc_parse_mob2(struct spawn_data* mob);
|
||||
struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
|
||||
|
||||
@@ -344,6 +344,17 @@ struct PACKET_ZC_FRIENDS_LIST{
|
||||
struct PACKET_ZC_FRIENDS_LIST_sub friends[];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_PC_SELL_ITEMLIST_sub {
|
||||
uint16 index;
|
||||
uint16 amount;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_PC_SELL_ITEMLIST {
|
||||
int16 packetType;
|
||||
int16 packetLength;
|
||||
PACKET_CZ_PC_SELL_ITEMLIST_sub sellList[];
|
||||
} __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 )
|
||||
@@ -412,6 +423,7 @@ DEFINE_PACKET_HEADER(CZ_REQUEST_RESET_ENCHANT, 0x0b9e)
|
||||
DEFINE_PACKET_HEADER(ZC_RESPONSE_ENCHANT, 0x0b9f)
|
||||
DEFINE_PACKET_HEADER(CZ_CLOSE_UI_ENCHANT, 0x0ba0)
|
||||
DEFINE_PACKET_HEADER(CZ_USE_PACKAGEITEM, 0x0baf)
|
||||
DEFINE_PACKET_HEADER(CZ_PC_SELL_ITEMLIST, 0x00c9)
|
||||
|
||||
const int16 MAX_INVENTORY_ITEM_PACKET_NORMAL = ( ( INT16_MAX - ( sizeof( struct packet_itemlist_normal ) - ( sizeof( struct NORMALITEM_INFO ) * MAX_ITEMLIST) ) ) / sizeof( struct NORMALITEM_INFO ) );
|
||||
const int16 MAX_INVENTORY_ITEM_PACKET_EQUIP = ( ( INT16_MAX - ( sizeof( struct packet_itemlist_equip ) - ( sizeof( struct EQUIPITEM_INFO ) * MAX_ITEMLIST ) ) ) / sizeof( struct EQUIPITEM_INFO ) );
|
||||
|
||||
Reference in New Issue
Block a user