From c1ab5a9db773d399c86eb59a3dded649387480c0 Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 22 Feb 2016 02:46:55 +0100 Subject: Edited npc->cashshop_buylist() to use the new struct itemlist - The npc-side code no longer depends on the client packet data layout. Signed-off-by: Haru --- src/map/clif.c | 19 ++++++++++++++----- src/map/npc.c | 42 ++++++++++++++++++++---------------------- src/map/npc.h | 4 +++- 3 files changed, 37 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 5e0c6f568..9e0977cc4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -15434,16 +15434,25 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd) int len = RFIFOW(fd,2); int points = RFIFOL(fd,4); int count = RFIFOW(fd,8); - unsigned short *item_list = NULL; + struct itemlist item_list = { 0 }; + int i; if( len < 10 || len != 10 + count * 4) { ShowWarning("Player %d sent incorrect cash shop buy packet (len %d:%d)!\n", sd->status.char_id, len, 10 + count * 4); return; } - item_list = aMalloc(sizeof(*item_list) * 2 * count); - memcpy(item_list, RFIFOP(fd,10), sizeof(*item_list) * 2 * count); - fail = npc->cashshop_buylist(sd,points,count,item_list); - aFree(item_list); + VECTOR_INIT(item_list); + VECTOR_ENSURE(item_list, count, 1); + for (i = 0; i < count; i++) { + struct itemlist_entry entry = { 0 }; + + entry.amount = RFIFOW(fd, 10 + 4 * i); + entry.id = RFIFOW(fd, 10 + 4 * i + 2); // Nameid + + VECTOR_PUSH(item_list, entry); + } + fail = npc->cashshop_buylist(sd, points, &item_list); + VECTOR_CLEAR(item_list); #endif } diff --git a/src/map/npc.c b/src/map/npc.c index 7ef0ba36a..793ca9a03 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1386,8 +1386,9 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) { /*========================================== * Cash Shop Buy List *------------------------------------------*/ -int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) { - int i, j, nameid, amount, new_, w, vt; +int npc_cashshop_buylist(struct map_session_data *sd, int points, struct itemlist *item_list) +{ + int i, j, new_, w, vt; struct npc_data *nd = NULL; struct npc_item_list *shop = NULL; unsigned short shop_size = 0; @@ -1395,7 +1396,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns if( sd->state.trading ) return ERROR_TYPE_EXCHANGE; - if( count <= 0 ) + if (VECTOR_LENGTH(*item_list) <= 0) return ERROR_TYPE_ITEM_ID; if( points < 0 ) @@ -1421,24 +1422,23 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns vt = 0; // Global Value // Validating Process ---------------------------------------------------- - for( i = 0; i < count; i++ ) { - nameid = item_list[i*2+1]; - amount = item_list[i*2+0]; + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); - if( !itemdb->exists(nameid) || amount <= 0 ) + if (!itemdb->exists(entry->id) || entry->amount <= 0) return ERROR_TYPE_ITEM_ID; - ARR_FIND(0,shop_size,j,shop[j].nameid == nameid); - if( j == shop_size || shop[j].value <= 0 ) + ARR_FIND(0,shop_size,j,shop[j].nameid == entry->id); + if (j == shop_size || shop[j].value <= 0) return ERROR_TYPE_ITEM_ID; - if( !itemdb->isstackable(nameid) && amount > 1 ) { + if (!itemdb->isstackable(entry->id) && entry->amount > 1) { ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of non-stackable item %d!\n", - sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); - amount = item_list[i*2+0] = 1; + sd->status.name, sd->status.account_id, sd->status.char_id, entry->amount, entry->id); + entry->amount = 1; } - switch( pc->checkadditem(sd,nameid,amount) ) { + switch (pc->checkadditem(sd, entry->id, entry->amount)) { case ADDITEM_NEW: new_++; break; @@ -1446,8 +1446,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns return ERROR_TYPE_INVENTORY_WEIGHT; } - vt += shop[j].value * amount; - w += itemdb_weight(nameid) * amount; + vt += shop[j].value * entry->amount; + w += itemdb_weight(entry->id) * entry->amount; } if( w + sd->weight > sd->max_weight ) @@ -1468,18 +1468,16 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns pc->paycash(sd,vt,points); } // Delivery Process ---------------------------------------------------- - for( i = 0; i < count; i++ ) { + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { + struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); struct item item_tmp; - nameid = item_list[i*2+1]; - amount = item_list[i*2+0]; - memset(&item_tmp,0,sizeof(item_tmp)); - if( !pet->create_egg(sd,nameid) ) { - item_tmp.nameid = nameid; + if (!pet->create_egg(sd, entry->id)) { + item_tmp.nameid = entry->id; item_tmp.identify = 1; - pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC); + pc->additem(sd, &item_tmp, entry->amount, LOG_TYPE_NPC); } } diff --git a/src/map/npc.h b/src/map/npc.h index be878933e..2731d51db 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -29,7 +29,9 @@ #include +/* Forward declarations */ struct hplugin_data_store; +struct itemlist; // map/itemdb.h struct view_data; enum npc_parse_options { @@ -230,7 +232,7 @@ struct npc_interface { int (*click) (struct map_session_data *sd, struct npc_data *nd); int (*scriptcont) (struct map_session_data *sd, int id, bool closing); int (*buysellsel) (struct map_session_data *sd, int id, int type); - int (*cashshop_buylist) (struct map_session_data *sd, int points, int count, unsigned short *item_list); + int (*cashshop_buylist) (struct map_session_data *sd, int points, struct itemlist *item_list); int (*buylist_sub) (struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd); int (*cashshop_buy) (struct map_session_data *sd, int nameid, int amount, int points); int (*buylist) (struct map_session_data *sd, int n, unsigned short *item_list); -- cgit v1.2.3-70-g09d2