summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog.txt3
-rw-r--r--src/map/trade.c163
2 files changed, 91 insertions, 75 deletions
diff --git a/Changelog.txt b/Changelog.txt
index 8b4eebfe9..1e2588b15 100644
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -1,5 +1,8 @@
Date Added
+01/27
+ * Fixed TRADE exploits (it cures proxy hack / vending+trade hack) thanks to Freya [Lupus]
+
01/26
* Added bug fix for a memory leak caused when a character logs out,
by End_of_exam / jA 1108 [celest]
diff --git a/src/map/trade.c b/src/map/trade.c
index 33b061a46..91b21a38b 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -141,7 +141,8 @@ void trade_tradeok(struct map_session_data *sd)
int trade_i;
nullpo_retv(sd);
-
+
+ // check items
for(trade_i=0;trade_i<10;trade_i++) {
int idx = sd->deal_item_index[trade_i]-2;
if(((idx >= 0) && (sd->deal_item_amount[trade_i]>sd->status.inventory[idx].amount)) || sd->deal_item_amount[trade_i]<0) {
@@ -150,6 +151,12 @@ void trade_tradeok(struct map_session_data *sd)
}
}
+
+ // check zeny
+ if (sd->deal_zeny < 0 || sd->deal_zeny > MAX_ZENY || sd->deal_zeny > sd->status.zeny) { // check amount
+ trade_tradecancel(sd);
+ return;
+ }
if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
sd->deal_locked=1;
@@ -204,94 +211,100 @@ void trade_tradecancel(struct map_session_data *sd)
* Žๆˆ๘‹–‘๘(trade‰Ÿ‚ต)
*------------------------------------------
*/
-void trade_tradecommit(struct map_session_data *sd)
-{
+void trade_tradecommit(struct map_session_data *sd) {
struct map_session_data *target_sd;
int trade_i;
+ int flag;
nullpo_retv(sd);
- if((target_sd = map_id2sd(sd->trade_partner)) != NULL){
- if( (sd->deal_locked >=1) && (target_sd->deal_locked >=1) ){ // both have pressed 'ok'
- if(sd->deal_locked < 2) {sd->deal_locked=2;} // set locked to 2
- if(target_sd->deal_locked==2) { // the other one pressed 'trade' too
- for(trade_i=0; trade_i<10;trade_i++) {
- if(sd->deal_item_amount[trade_i] != 0) {
- int n=sd->deal_item_index[trade_i]-2;
- int flag;
+ if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) {
+ if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1)) { // both have pressed 'ok'
+ if (sd->deal_locked < 2) {sd->deal_locked = 2;} // set locked to 2
+ if (target_sd->deal_locked == 2) { // the other one pressed 'trade' too
+ // check zenys value against hackers
+ if (sd->deal_zeny >= 0 && sd->deal_zeny <= MAX_ZENY && sd->deal_zeny <= sd->status.zeny && // check amount
+ (target_sd->status.zeny + sd->deal_zeny) <= MAX_ZENY && // fix positiv overflow
+ target_sd->deal_zeny >= 0 && target_sd->deal_zeny <= MAX_ZENY && target_sd->deal_zeny <= target_sd->status.zeny && // check amount
+ (sd->status.zeny + target_sd->deal_zeny) <= MAX_ZENY) { // fix positiv overflow
- //Dupe Fix by mark
- if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i])
- sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount;
- //End Dupe Fix
+ // trade is accepted
+ for(trade_i = 0; trade_i < 10; trade_i++) {
+ if (sd->deal_item_amount[trade_i] != 0) {
+ int n = sd->deal_item_index[trade_i] - 2;
- #ifndef TXT_ONLY
- if(log_config.trade > 0)
- log_trade(sd,target_sd,n,sd->deal_item_amount[trade_i]);
- #endif //USE_SQL
+ if (sd->status.inventory[n].amount < sd->deal_item_amount[trade_i])
+ sd->deal_item_amount[trade_i] = sd->status.inventory[n].amount;
- flag = pc_additem(target_sd,&sd->status.inventory[n],sd->deal_item_amount[trade_i]);
- if(flag==0)
- pc_delitem(sd,n,sd->deal_item_amount[trade_i],1);
- else
- clif_additem(sd,n,sd->deal_item_amount[trade_i],0);
- sd->deal_item_index[trade_i] =0;
- sd->deal_item_amount[trade_i]=0;
- }
- if(target_sd->deal_item_amount[trade_i] != 0) {
- int n=target_sd->deal_item_index[trade_i]-2;
- int flag;
+ #ifndef TXT_ONLY
+ if(log_config.trade > 0)
+ log_trade(sd,target_sd,n,sd->deal_item_amount[trade_i]);
+ #endif //USE_SQL
- //Dupe Fix by mark
- if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i])
- target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount;
- //End Dupe Fix
+ flag = pc_additem(target_sd, &sd->status.inventory[n], sd->deal_item_amount[trade_i]);
+ if (flag == 0)
+ pc_delitem(sd, n, sd->deal_item_amount[trade_i], 1);
+ else
+ clif_additem(sd, n, sd->deal_item_amount[trade_i], 0);
+ sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_amount[trade_i] = 0;
+ }
+ if (target_sd->deal_item_amount[trade_i] != 0) {
+ int n = target_sd->deal_item_index[trade_i] - 2;
- #ifndef TXT_ONLY
- if(log_config.trade > 0)
- log_trade(target_sd,sd,n,target_sd->deal_item_amount[trade_i]);
- #endif //USE_SQL
+ if (target_sd->status.inventory[n].amount < target_sd->deal_item_amount[trade_i])
+ target_sd->deal_item_amount[trade_i] = target_sd->status.inventory[n].amount;
+
+ #ifndef TXT_ONLY
+ if(log_config.trade > 0)
+ log_trade(target_sd,sd,n,target_sd->deal_item_amount[trade_i]);
+ #endif //USE_SQL
- flag = pc_additem(sd,&target_sd->status.inventory[n],target_sd->deal_item_amount[trade_i]);
- if(flag==0)
- pc_delitem(target_sd,n,target_sd->deal_item_amount[trade_i],1);
- else
- clif_additem(target_sd,n,target_sd->deal_item_amount[trade_i],0);
- target_sd->deal_item_index[trade_i] =0;
- target_sd->deal_item_amount[trade_i]=0;
+ flag = pc_additem(sd, &target_sd->status.inventory[n], target_sd->deal_item_amount[trade_i]);
+ if (flag == 0)
+ pc_delitem(target_sd, n, target_sd->deal_item_amount[trade_i], 1);
+ else
+ clif_additem(target_sd, n, target_sd->deal_item_amount[trade_i], 0);
+ target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_amount[trade_i] = 0;
+ }
}
- }
- if(sd->deal_zeny) {
+ if (sd->deal_zeny) {
+ #ifndef TXT_ONLY
+ if (log_config.trade > 0 && log_config.zeny > 0)
+ log_zeny(sd, target_sd, sd->deal_zeny);
+ #endif //USE_SQL
+ sd->status.zeny -= sd->deal_zeny;
+ target_sd->status.zeny += sd->deal_zeny;
+ }
+ if (target_sd->deal_zeny) {
#ifndef TXT_ONLY
- if (log_config.trade > 0 && log_config.zeny > 0)
- log_zeny(sd, target_sd, sd->deal_zeny);
- #endif //USE_SQL
- sd->status.zeny -= sd->deal_zeny;
- clif_updatestatus(sd,SP_ZENY);
- target_sd->status.zeny += sd->deal_zeny;
- clif_updatestatus(target_sd,SP_ZENY);
- sd->deal_zeny=0;
- }
- if(target_sd->deal_zeny) {
- #ifndef TXT_ONLY
- if (log_config.trade > 0 && log_config.zeny > 0)
- log_zeny(target_sd, sd, target_sd->deal_zeny);
- #endif //USE_SQL
- target_sd->status.zeny -= target_sd->deal_zeny;
- clif_updatestatus(target_sd,SP_ZENY);
- sd->status.zeny += target_sd->deal_zeny;
- clif_updatestatus(sd,SP_ZENY);
- target_sd->deal_zeny=0;
+ if (log_config.trade > 0 && log_config.zeny > 0)
+ log_zeny(target_sd, sd, sd->deal_zeny);
+ #endif //USE_SQL
+
+ target_sd->status.zeny -= target_sd->deal_zeny;
+ sd->status.zeny += target_sd->deal_zeny;
+ }
+ if (sd->deal_zeny || target_sd->deal_zeny) {
+ clif_updatestatus(sd, SP_ZENY);
+ sd->deal_zeny = 0;
+ clif_updatestatus(target_sd, SP_ZENY);
+ target_sd->deal_zeny = 0;
+ }
+ sd->deal_locked = 0;
+ sd->trade_partner = 0;
+ target_sd->deal_locked = 0;
+ target_sd->trade_partner = 0;
+ clif_tradecompleted(sd, 0);
+ clif_tradecompleted(target_sd, 0);
+ // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
+ chrif_save(sd); // do pc_makesavestatus and save storage too
+ chrif_save(target_sd); // do pc_makesavestatus and save storage too
+ // zeny value was modified!!!! hacker with packet modified
+ } else {
+ trade_tradecancel(sd);
}
- sd->deal_locked =0;
- sd->trade_partner=0;
- target_sd->deal_locked=0;
- target_sd->trade_partner=0;
- clif_tradecompleted(sd,0);
- clif_tradecompleted(target_sd,0);
- // save both player to avoid crash: they always have no advantage/disadvantage between the 2 players [Yor]
- chrif_save(sd); // do pc_makesavestatus and save storage too
- chrif_save(target_sd); // do pc_makesavestatus and save storage too
}
}
}