Additional fixes for cart exploit (#4148)
* Fixes #4146.
* Reverted some of 7f772c3 as this falls into a larger refactor scope.
* Resolved an issue where items could not be picked up from the cart when the overweight message was sent to the player.
* Added missing e_additem_result constants.
Thanks to @secretdataz, @Normynator, and @cydh!
This commit is contained in:
committed by
Aleos
parent
3ad276c9ef
commit
7ad1b32d7d
@@ -4806,13 +4806,13 @@ short pc_search_inventory(struct map_session_data *sd, unsigned short nameid) {
|
||||
* 6 = ?
|
||||
* 7 = stack limitation
|
||||
*/
|
||||
char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type) {
|
||||
enum e_additem_result pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type) {
|
||||
struct item_data *id;
|
||||
int16 i;
|
||||
unsigned int w;
|
||||
|
||||
nullpo_retr(1, sd);
|
||||
nullpo_retr(1, item);
|
||||
nullpo_retr(ADDITEM_INVALID, sd);
|
||||
nullpo_retr(ADDITEM_INVALID, item);
|
||||
|
||||
if( item->nameid == 0 || amount <= 0 )
|
||||
return ADDITEM_INVALID;
|
||||
@@ -5342,33 +5342,33 @@ int pc_useitem(struct map_session_data *sd,int n)
|
||||
* @param item
|
||||
* @param amount
|
||||
* @param log_type
|
||||
* @return 0 = success; 1 = fail; 2 = no slot
|
||||
* @return See pc.hpp::e_additem_result
|
||||
*/
|
||||
unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type)
|
||||
enum e_additem_result pc_cart_additem(struct map_session_data *sd,struct item *item,int amount,e_log_pick_type log_type)
|
||||
{
|
||||
struct item_data *data;
|
||||
int i,w;
|
||||
|
||||
nullpo_retr(1, sd);
|
||||
nullpo_retr(1, item);
|
||||
nullpo_retr(ADDITEM_INVALID, sd);
|
||||
nullpo_retr(ADDITEM_INVALID, item);
|
||||
|
||||
if(item->nameid == 0 || amount <= 0)
|
||||
return 1;
|
||||
return ADDITEM_INVALID;
|
||||
data = itemdb_search(item->nameid);
|
||||
|
||||
if( data->stack.cart && amount > data->stack.amount )
|
||||
{// item stack limitation
|
||||
return 1;
|
||||
return ADDITEM_STACKLIMIT;
|
||||
}
|
||||
|
||||
if( !itemdb_cancartstore(item, pc_get_group_level(sd)) || (item->bound > BOUND_ACCOUNT && !pc_can_give_bounded_items(sd)))
|
||||
{ // Check item trade restrictions [Skotlex]
|
||||
clif_displaymessage (sd->fd, msg_txt(sd,264));
|
||||
return 1;
|
||||
return ADDITEM_INVALID;
|
||||
}
|
||||
|
||||
if( (w = data->weight*amount) + sd->cart_weight > sd->cart_weight_max )
|
||||
return 1;
|
||||
return ADDITEM_OVERWEIGHT;
|
||||
|
||||
i = MAX_CART;
|
||||
if( itemdb_isstackable2(data) && !item->expire_time )
|
||||
@@ -5386,7 +5386,7 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int
|
||||
if( i < MAX_CART )
|
||||
{// item already in cart, stack it
|
||||
if( amount > MAX_AMOUNT - sd->cart.u.items_cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->cart.u.items_cart[i].amount ) )
|
||||
return 2; // no slot
|
||||
return ADDITEM_OVERAMOUNT; // no slot
|
||||
|
||||
sd->cart.u.items_cart[i].amount += amount;
|
||||
clif_cart_additem(sd,i,amount,0);
|
||||
@@ -5395,7 +5395,7 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int
|
||||
{// item not stackable or not present, add it
|
||||
ARR_FIND( 0, MAX_CART, i, sd->cart.u.items_cart[i].nameid == 0 );
|
||||
if( i == MAX_CART )
|
||||
return 2; // no slot
|
||||
return ADDITEM_OVERAMOUNT; // no slot
|
||||
|
||||
memcpy(&sd->cart.u.items_cart[i],item,sizeof(sd->cart.u.items_cart[0]));
|
||||
sd->cart.u.items_cart[i].id = 0;
|
||||
@@ -5410,7 +5410,7 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int
|
||||
sd->cart_weight += w;
|
||||
clif_updatestatus(sd,SP_CARTINFO);
|
||||
|
||||
return 0;
|
||||
return ADDITEM_SUCCESS;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@@ -5443,15 +5443,12 @@ void pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log
|
||||
*------------------------------------------*/
|
||||
void pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
|
||||
{
|
||||
struct item *item_data;
|
||||
char flag;
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
if (idx < 0 || idx >= MAX_INVENTORY) //Invalid index check [Skotlex]
|
||||
return;
|
||||
|
||||
item_data = &sd->inventory.u.items_inventory[idx];
|
||||
struct item *item_data = &sd->inventory.u.items_inventory[idx];
|
||||
|
||||
if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending || sd->state.prevend )
|
||||
return;
|
||||
@@ -5461,11 +5458,14 @@ void pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
|
||||
return;
|
||||
}
|
||||
|
||||
if( (flag = pc_cart_additem(sd,item_data,amount,LOG_TYPE_NONE)) == 0 )
|
||||
enum e_additem_result flag = pc_cart_additem(sd,item_data,amount,LOG_TYPE_NONE);
|
||||
|
||||
if (flag == ADDITEM_SUCCESS)
|
||||
pc_delitem(sd,idx,amount,0,5,LOG_TYPE_NONE);
|
||||
else {
|
||||
clif_dropitem(sd,idx,0);
|
||||
clif_cart_additem_ack(sd,(flag==1)?ADDITEM_TO_CART_FAIL_WEIGHT:ADDITEM_TO_CART_FAIL_COUNT);
|
||||
clif_delitem(sd, idx, amount, flag);
|
||||
clif_cart_additem_ack(sd, (flag == ADDITEM_OVERAMOUNT) ? ADDITEM_TO_CART_FAIL_COUNT : ADDITEM_TO_CART_FAIL_WEIGHT);
|
||||
clif_additem(sd, idx, amount, flag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5498,22 +5498,19 @@ void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
|
||||
if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex]
|
||||
return;
|
||||
|
||||
item* item_data=&sd->cart.u.items_cart[idx];
|
||||
struct item *item_data=&sd->cart.u.items_cart[idx];
|
||||
|
||||
if (item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending || sd->state.prevend)
|
||||
return;
|
||||
|
||||
if (pc_checkadditem(sd, item_data->nameid, amount) == CHKADDITEM_OVERAMOUNT) {
|
||||
return;
|
||||
}
|
||||
enum e_additem_result flag = pc_additem(sd, item_data, amount, LOG_TYPE_NONE);
|
||||
|
||||
item item_copy = *item_data;
|
||||
|
||||
pc_cart_delitem(sd, idx, amount, 0, LOG_TYPE_NONE);
|
||||
char flag = pc_additem(sd, &item_copy, amount, LOG_TYPE_NONE);
|
||||
if(flag != ADDITEM_SUCCESS) {
|
||||
clif_dropitem(sd,idx,0);
|
||||
clif_additem(sd,0,0,flag);
|
||||
if (flag == ADDITEM_SUCCESS)
|
||||
pc_cart_delitem(sd, idx, amount, 0, LOG_TYPE_NONE);
|
||||
else {
|
||||
clif_cart_delitem(sd, idx, amount);
|
||||
clif_additem(sd, idx, amount, flag);
|
||||
clif_cart_additem(sd, idx, amount, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,23 @@ enum prevent_logout_trigger {
|
||||
PLT_DAMAGE = 8
|
||||
};
|
||||
|
||||
enum e_chkitem_result : uint8 {
|
||||
CHKADDITEM_EXIST,
|
||||
CHKADDITEM_NEW,
|
||||
CHKADDITEM_OVERAMOUNT
|
||||
};
|
||||
|
||||
enum e_additem_result : uint8 {
|
||||
ADDITEM_SUCCESS,
|
||||
ADDITEM_INVALID,
|
||||
ADDITEM_OVERWEIGHT,
|
||||
ADDITEM_ITEM,
|
||||
ADDITEM_OVERITEM,
|
||||
ADDITEM_OVERAMOUNT,
|
||||
ADDITEM_REFUSED_TIME,
|
||||
ADDITEM_STACKLIMIT
|
||||
};
|
||||
|
||||
struct skill_cooldown_entry {
|
||||
unsigned short skill_id;
|
||||
int timer;
|
||||
@@ -1049,7 +1066,7 @@ char pc_checkadditem(struct map_session_data *sd, unsigned short nameid, int amo
|
||||
uint8 pc_inventoryblank(struct map_session_data *sd);
|
||||
short pc_search_inventory(struct map_session_data *sd, unsigned short nameid);
|
||||
char pc_payzeny(struct map_session_data *sd, int zeny, enum e_log_pick_type type, struct map_session_data *tsd);
|
||||
char pc_additem(struct map_session_data *sd, struct item *item, int amount, e_log_pick_type log_type);
|
||||
enum e_additem_result pc_additem(struct map_session_data *sd, struct item *item, int amount, e_log_pick_type log_type);
|
||||
char pc_getzeny(struct map_session_data *sd, int zeny, enum e_log_pick_type type, struct map_session_data *tsd);
|
||||
char pc_delitem(struct map_session_data *sd, int n, int amount, int type, short reason, e_log_pick_type log_type);
|
||||
|
||||
@@ -1062,7 +1079,7 @@ int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist);
|
||||
int pc_paycash( struct map_session_data *sd, int price, int points, e_log_pick_type type );
|
||||
int pc_getcash( struct map_session_data *sd, int cash, int points, e_log_pick_type type );
|
||||
|
||||
unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type);
|
||||
enum e_additem_result pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type);
|
||||
void pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type);
|
||||
void pc_putitemtocart(struct map_session_data *sd,int idx,int amount);
|
||||
void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount);
|
||||
@@ -1253,21 +1270,6 @@ void pc_readdb(void);
|
||||
void do_init_pc(void);
|
||||
void do_final_pc(void);
|
||||
|
||||
enum e_chkitem_result {
|
||||
CHKADDITEM_EXIST,
|
||||
CHKADDITEM_NEW,
|
||||
CHKADDITEM_OVERAMOUNT
|
||||
};
|
||||
|
||||
enum e_additem_result {
|
||||
ADDITEM_SUCCESS,
|
||||
ADDITEM_INVALID,
|
||||
ADDITEM_OVERWEIGHT,
|
||||
ADDITEM_OVERITEM = 4,
|
||||
ADDITEM_OVERAMOUNT,
|
||||
ADDITEM_STACKLIMIT = 7
|
||||
};
|
||||
|
||||
// timer for night.day
|
||||
extern int day_timer_tid;
|
||||
extern int night_timer_tid;
|
||||
|
||||
@@ -409,6 +409,10 @@ void storage_storageaddfromcart(struct map_session_data *sd, struct s_storage *s
|
||||
enum e_storage_add result;
|
||||
nullpo_retv(sd);
|
||||
|
||||
if (sd->state.prevend) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = storage_canAddItem(stor, index, sd->cart.u.items_inventory, amount, MAX_CART);
|
||||
if (result == STORAGE_ADD_INVALID)
|
||||
return;
|
||||
@@ -444,6 +448,10 @@ void storage_storagegettocart(struct map_session_data* sd, struct s_storage *sto
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
if (sd->state.prevend) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = storage_canGetItem(stor, index, amount);
|
||||
if (result != STORAGE_ADD_OK)
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user