From 4e406f3ed6e6f8b2b8434a366a5e54c8f7186f45 Mon Sep 17 00:00:00 2001 From: glighta Date: Wed, 14 Nov 2012 02:26:00 +0000 Subject: Following r16914 -fix @zeny for negative amout bugreport:6886, bugreport:6895 bugreport:6888 -fix @cash,@points command display result -enforce bound chk for both git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16924 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 47 ++++++++++++++++++++++++++++++----------------- src/map/intif.c | 2 +- src/map/mail.c | 1 - src/map/party.c | 2 +- src/map/pc.c | 21 ++++++++++++++++----- src/map/pc.h | 4 ++-- src/map/trade.c | 49 ++++++++++++++++++++++++++----------------------- 7 files changed, 76 insertions(+), 50 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 27329ae4a..891fb1a79 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2522,7 +2522,7 @@ ACMD_FUNC(skillpoint) } /*========================================== - * @zeny (Rewritten by [Yor]) + * @zeny *------------------------------------------*/ ACMD_FUNC(zeny) { @@ -2533,10 +2533,14 @@ ACMD_FUNC(zeny) clif_displaymessage(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny ). return -1; } - if(zeny > 0) - pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL); - else - pc_payzeny(sd,zeny,LOG_TYPE_COMMAND,NULL); + + if(zeny > 0){ + if(pc_getzeny(sd,zeny,LOG_TYPE_COMMAND,NULL) == 1) + clif_displaymessage(fd, msg_txt(149)); // Unable to increase the number/value. + } + else if(pc_payzeny(sd,-zeny,LOG_TYPE_COMMAND,NULL) == 1){ + clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value. + } return 0; } @@ -7858,6 +7862,7 @@ ACMD_FUNC(cash) { char output[128]; int value; + int ret=0; nullpo_retr(-1, sd); if( !message || !*message || (value = atoi(message)) == 0 ) { @@ -7868,25 +7873,33 @@ ACMD_FUNC(cash) if( !strcmpi(command+1,"cash") ) { if( value > 0 ) { - pc_getcash(sd, value, 0); - sprintf(output, msg_txt(505), value, sd->cashPoints); - clif_disp_onlyself(sd, output, strlen(output)); + if( (ret=pc_getcash(sd, value, 0)) >= 0){ + sprintf(output, msg_txt(505), ret, sd->cashPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value. } else { - pc_paycash(sd, -value, 0); - sprintf(output, msg_txt(410), value, sd->cashPoints); - clif_disp_onlyself(sd, output, strlen(output)); + if( (ret=pc_paycash(sd, -value, 0)) >= 0){ + sprintf(output, msg_txt(410), ret, sd->cashPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value. } } else { // @points if( value > 0 ) { - pc_getcash(sd, 0, value); - sprintf(output, msg_txt(506), value, sd->kafraPoints); - clif_disp_onlyself(sd, output, strlen(output)); + if( (ret=pc_getcash(sd, 0, value)) >= 0){ + sprintf(output, msg_txt(506), ret, sd->kafraPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value. } else { - pc_paycash(sd, -value, -value); - sprintf(output, msg_txt(411), -value, sd->kafraPoints); - clif_disp_onlyself(sd, output, strlen(output)); + if( (ret=pc_paycash(sd, -value, -value)) >= 0){ + sprintf(output, msg_txt(411), ret, sd->kafraPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + else clif_displaymessage(fd, msg_txt(41)); // Unable to decrease the number/value. } } diff --git a/src/map/intif.c b/src/map/intif.c index a06334e77..3bbb92216 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1827,7 +1827,7 @@ static void intif_parse_Auction_register(int fd) clif_Auction_message(sd->fd, 4); pc_additem(sd, &auction.item, auction.item.amount, LOG_TYPE_AUCTION); - pc_getzeny(sd, zeny, LOG_TYPE_AUCTION,NULL); + pc_getzeny(sd, zeny, LOG_TYPE_AUCTION, NULL); } } diff --git a/src/map/mail.c b/src/map/mail.c index 62d046ea4..03b8227b5 100644 --- a/src/map/mail.c +++ b/src/map/mail.c @@ -51,7 +51,6 @@ int mail_removezeny(struct map_session_data *sd, short flag) pc_payzeny(sd,sd->mail.zeny,LOG_TYPE_MAIL, NULL); } sd->mail.zeny = 0; - clif_updatestatus(sd, SP_ZENY); return 1; } diff --git a/src/map/party.c b/src/map/party.c index dfcae5421..f7a2ebc6a 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -949,7 +949,7 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b pc_gainexp(sd[i], src, base_exp, job_exp, false); if (zeny) // zeny from mobs [Valaris] - pc_getzeny(sd[i],zeny,LOG_TYPE_OTHER,NULL); + pc_getzeny(sd[i],zeny,LOG_TYPE_PICKDROP_MONSTER,NULL); } return 0; } diff --git a/src/map/pc.c b/src/map/pc.c index 986087484..b54b88ae2 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3590,6 +3590,7 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, { nullpo_ret(sd); + zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB if( zeny < 0 ) { ShowError("pc_payzeny: Paying negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id); @@ -3616,16 +3617,17 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, * Cash Shop *------------------------------------------*/ -void pc_paycash(struct map_session_data *sd, int price, int points) +int pc_paycash(struct map_session_data *sd, int price, int points) { char output[128]; int cash; nullpo_retv(sd); + points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB if( price < 0 || points < 0 ) { ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id); - return; + return -2; } if( points > price ) @@ -3639,7 +3641,7 @@ void pc_paycash(struct map_session_data *sd, int price, int points) if( sd->cashPoints < cash || sd->kafraPoints < points ) { ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id); - return; + return -1; } pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash); @@ -3650,13 +3652,16 @@ void pc_paycash(struct map_session_data *sd, int price, int points) sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints); clif_disp_onlyself(sd, output, strlen(output)); } + return cash+points; } -void pc_getcash(struct map_session_data *sd, int cash, int points) +int pc_getcash(struct map_session_data *sd, int cash, int points) { char output[128]; nullpo_retv(sd); + cash = cap_value(cash,-MAX_ZENY,MAX_ZENY); //prevent command UB + points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB if( cash > 0 ) { if( cash > MAX_ZENY-sd->cashPoints ) @@ -3672,10 +3677,12 @@ void pc_getcash(struct map_session_data *sd, int cash, int points) sprintf(output, msg_txt(505), cash, sd->cashPoints); clif_disp_onlyself(sd, output, strlen(output)); } + return cash; } else if( cash < 0 ) { ShowError("pc_getcash: Obtaining negative cash points (cash=%d, account_id=%d, char_id=%d).\n", cash, sd->status.account_id, sd->status.char_id); + return -1; } if( points > 0 ) @@ -3693,11 +3700,14 @@ void pc_getcash(struct map_session_data *sd, int cash, int points) sprintf(output, msg_txt(506), points, sd->kafraPoints); clif_disp_onlyself(sd, output, strlen(output)); } + return points; } else if( points < 0 ) { ShowError("pc_getcash: Obtaining negative kafra points (points=%d, account_id=%d, char_id=%d).\n", points, sd->status.account_id, sd->status.char_id); + return -1; } + return -2; //shouldn't happen but jsut in case } /*========================================== @@ -3708,6 +3718,7 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, { nullpo_ret(sd); + zeny = cap_value(zeny,-MAX_ZENY,MAX_ZENY); //prevent command UB if( zeny < 0 ) { ShowError("pc_getzeny: Obtaining negative Zeny (zeny=%d, account_id=%d, char_id=%d).\n", zeny, sd->status.account_id, sd->status.char_id); @@ -3720,7 +3731,7 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, sd->status.zeny += zeny; clif_updatestatus(sd,SP_ZENY); - if(!sd) tsd = sd; + if(!tsd) tsd = sd; log_zeny(sd, type, tsd, zeny); if( zeny > 0 && sd->state.showzeny ) { char output[255]; diff --git a/src/map/pc.h b/src/map/pc.h index 1cc81eb9c..bc8a76f2a 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -701,8 +701,8 @@ int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_se int pc_delitem(struct map_session_data*,int,int,int,short,e_log_pick_type); // Special Shop System -void pc_paycash(struct map_session_data *sd, int price, int points); -void pc_getcash(struct map_session_data *sd, int cash, int points); +int pc_paycash(struct map_session_data *sd, int price, int points); +int pc_getcash(struct map_session_data *sd, int cash, int points); int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type); int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type); diff --git a/src/map/trade.c b/src/map/trade.c index ac23b047e..0d01b54a6 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -74,15 +74,15 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta clif_displaymessage(sd->fd, msg_txt(246)); clif_tradestart(sd, 2); // GM is not allowed to trade return; - } - + } + // Players can not request trade from far away, unless they are allowed to use @trade. if (!pc_can_use_command(sd, "trade", COMMAND_ATCOMMAND) && (sd->bl.m != target_sd->bl.m || !check_distance_bl(&sd->bl, &target_sd->bl, TRADE_DISTANCE))) { clif_tradestart(sd, 0); // too far return ; } - + target_sd->trade_partner = sd->status.account_id; sd->trade_partner = target_sd->status.account_id; clif_traderequest(target_sd, sd->status.name); @@ -106,7 +106,7 @@ void trade_tradeack(struct map_session_data *sd, int type) if (sd->state.trading || !sd->trade_partner) return; //Already trading or no partner set. - + if ((tsd = map_id2sd(sd->trade_partner)) == NULL) { clif_tradestart(sd, 1); // character does not exist sd->trade_partner=0; @@ -177,7 +177,7 @@ int impossible_trade_check(struct map_session_data *sd) int i, index; nullpo_retr(1, sd); - + if(sd->deal.zeny > sd->status.zeny) { pc_setglobalreg(sd,"ZENY_HACKER",1); @@ -220,7 +220,7 @@ int impossible_trade_check(struct map_session_data *sd) } else // message about the ban strcpy(message_to_gm, msg_txt(508)); // This player hasn't been banned (Ban option is disabled). - + intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm); return 1; } @@ -257,7 +257,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd) n = sd->deal.item[trade_i].index; if (amount > inventory[n].amount) return 0; //qty Exploit? - + data = itemdb_search(inventory[n].nameid); i = MAX_INVENTORY; if (itemdb_isstackable2(data)) { //Stackable item. @@ -272,7 +272,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd) break; } } - + if (i == MAX_INVENTORY) {// look for an empty slot. for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++); if (i == MAX_INVENTORY) @@ -439,7 +439,7 @@ void trade_tradeok(struct map_session_data *sd) if(sd->state.deal_locked || !sd->state.trading) return; - + if ((target_sd = map_id2sd(sd->trade_partner)) == NULL) { trade_tradecancel(sd); return; @@ -470,7 +470,7 @@ void trade_tradecancel(struct map_session_data *sd) clif_tradecancelled(sd); return; } - + for(trade_i = 0; trade_i < 10; trade_i++) { // give items back (only virtual) if (!sd->deal.item[trade_i].amount) continue; @@ -498,7 +498,7 @@ void trade_tradecancel(struct map_session_data *sd) target_sd->deal.item[trade_i].index = 0; target_sd->deal.item[trade_i].amount = 0; } - + if (target_sd->deal.zeny) { clif_updatestatus(target_sd, SP_ZENY); target_sd->deal.zeny = 0; @@ -525,9 +525,9 @@ void trade_tradecommit(struct map_session_data *sd) trade_tradecancel(sd); return; } - + sd->state.deal_locked = 2; - + if (tsd->state.deal_locked < 2) return; //Not yet time for trading. @@ -547,7 +547,7 @@ void trade_tradecommit(struct map_session_data *sd) trade_tradecancel(sd); return; } - + // trade is accepted and correct. for( trade_i = 0; trade_i < 10; trade_i++ ) { @@ -578,30 +578,33 @@ void trade_tradecommit(struct map_session_data *sd) } } - if( sd->deal.zeny || tsd->deal.zeny ) - { - pc_getzeny(sd,tsd->deal.zeny - sd->deal.zeny,LOG_TYPE_TRADE, tsd); - pc_getzeny(tsd,sd->deal.zeny - tsd->deal.zeny,LOG_TYPE_TRADE, sd); - + if( sd->deal.zeny ) { + pc_payzeny(sd ,sd->deal.zeny, LOG_TYPE_TRADE, tsd); + pc_getzeny(tsd,sd->deal.zeny,LOG_TYPE_TRADE, sd); sd->deal.zeny = 0; + + } + if ( tsd->deal.zeny) { + pc_payzeny(tsd,tsd->deal.zeny,LOG_TYPE_TRADE, sd); + pc_getzeny(sd ,tsd->deal.zeny,LOG_TYPE_TRADE, tsd); tsd->deal.zeny = 0; } - + sd->state.deal_locked = 0; sd->trade_partner = 0; sd->state.trading = 0; - + tsd->state.deal_locked = 0; tsd->trade_partner = 0; tsd->state.trading = 0; - + clif_tradecompleted(sd, 0); clif_tradecompleted(tsd, 0); // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players if (save_settings&1) { - chrif_save(sd,0); + chrif_save(sd,0); chrif_save(tsd,0); } } -- cgit v1.2.3-70-g09d2