summaryrefslogtreecommitdiff
path: root/src/map/trade.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/trade.c')
-rw-r--r--src/map/trade.c87
1 files changed, 52 insertions, 35 deletions
diff --git a/src/map/trade.c b/src/map/trade.c
index 6352c3a4d..e727c3c70 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -2,8 +2,8 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2015 Hercules Dev Team
- * Copyright (C) Athena Dev Teams
+ * Copyright (C) 2012-2020 Hercules Dev Team
+ * Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,19 +40,22 @@
#include <stdio.h>
#include <string.h>
-struct trade_interface trade_s;
+static struct trade_interface trade_s;
struct trade_interface *trade;
/*==========================================
* Initiates a trade request.
*------------------------------------------*/
-void trade_traderequest(struct map_session_data *sd, struct map_session_data *target_sd)
+static void trade_traderequest(struct map_session_data *sd, struct map_session_data *target_sd)
{
nullpo_retv(sd);
+ if (sd == target_sd)
+ return;
+
if (map->list[sd->bl.m].flag.notrade) {
- clif->message (sd->fd, msg_sd(sd,272));
- return; //Can't trade in notrade mapflag maps.
+ clif->message (sd->fd, msg_sd(sd,272)); // You can't trade in this map
+ return;
}
if (target_sd == NULL || sd == target_sd) {
@@ -90,7 +93,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) //check if both GMs are allowed to trade
{
- clif->message(sd->fd, msg_sd(sd,246));
+ clif->message(sd->fd, msg_sd(sd,246)); // Your GM level doesn't authorize you to perform this action.
clif->tradestart(sd, 2); // GM is not allowed to trade
return;
}
@@ -118,7 +121,8 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta
* Weird enough, the client should only send 3/4
* and the server is the one that can reply 0~2
*------------------------------------------*/
-void trade_tradeack(struct map_session_data *sd, int type) {
+static void trade_tradeack(struct map_session_data *sd, int type)
+{
struct map_session_data *tsd;
nullpo_retv(sd);
@@ -162,8 +166,8 @@ void trade_tradeack(struct map_session_data *sd, int type) {
}
//Check if you can start trade.
- if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag != STORAGE_FLAG_CLOSED
- || tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag != STORAGE_FLAG_CLOSED
+ if (sd->npc_id || sd->state.vending || sd->state.prevend || sd->state.buyingstore || sd->state.storage_flag != STORAGE_FLAG_CLOSED
+ || tsd->npc_id || tsd->state.vending || tsd->state.prevend || tsd->state.buyingstore || tsd->state.storage_flag != STORAGE_FLAG_CLOSED
) {
//Fail
clif->tradestart(sd, 2);
@@ -191,7 +195,7 @@ void trade_tradeack(struct map_session_data *sd, int type) {
* @retval 0 The trade can continue
* @retval 1 Hack attempt
**/
-int impossible_trade_check(struct map_session_data *sd)
+static int impossible_trade_check(struct map_session_data *sd)
{
struct item inventory[MAX_INVENTORY];
char message_to_gm[200];
@@ -208,7 +212,7 @@ int impossible_trade_check(struct map_session_data *sd)
// remove this part: arrows can be trade and equipped
// re-added! [celest]
// remove equipped items (they can not be trade)
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (i = 0; i < sd->status.inventorySize; i++)
if (inventory[i].nameid > 0 && inventory[i].equip && !(inventory[i].equip & EQP_AMMO))
memset(&inventory[i], 0, sizeof(struct item));
@@ -217,12 +221,14 @@ int impossible_trade_check(struct map_session_data *sd)
if (!sd->deal.item[i].amount)
continue;
index = sd->deal.item[i].index;
+ if (index < 0 || index >= sd->status.inventorySize)
+ return 1;
if (inventory[index].amount < sd->deal.item[i].amount) {
// if more than the player have -> hack
snprintf(message_to_gm, sizeof(message_to_gm), msg_txt(538), sd->status.name, sd->status.account_id); // Hack on trade: character '%s' (account: %d) try to trade more items that he has.
- intif->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
+ pc->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
snprintf(message_to_gm, sizeof(message_to_gm), msg_txt(539), inventory[index].amount, inventory[index].nameid, sd->deal.item[i].amount); // This player has %d of a kind of item (id: %d), and try to trade %d of them.
- intif->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
+ pc->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
// if we block people
if (battle_config.ban_hack_trade < 0) {
chrif->char_ask_name(-1, sd->status.name, CHAR_ASK_NAME_BLOCK, 0, 0, 0, 0, 0, 0);
@@ -239,7 +245,7 @@ int impossible_trade_check(struct map_session_data *sd)
// message about the ban
safestrncpy(message_to_gm, msg_txt(508), sizeof(message_to_gm)); // This player hasn't been banned (Ban option is disabled).
- intif->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
+ pc->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
return 1;
}
inventory[index].amount -= sd->deal.item[i].amount; // remove item from inventory
@@ -250,13 +256,15 @@ int impossible_trade_check(struct map_session_data *sd)
/*==========================================
* Checks if trade is possible (against zeny limits, inventory limits, etc)
*------------------------------------------*/
-int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
+static int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
{
struct item inventory[MAX_INVENTORY];
struct item inventory2[MAX_INVENTORY];
struct item_data *data;
int trade_i, i, n;
+ nullpo_ret(sd);
+ nullpo_ret(tsd);
// check zenys value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then.
if(sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny))
return 0;
@@ -276,9 +284,9 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
return 0; //qty Exploit?
data = itemdb->search(inventory[n].nameid);
- i = MAX_INVENTORY;
+ i = tsd->status.inventorySize;
if (itemdb->isstackable2(data)) { //Stackable item.
- for(i = 0; i < MAX_INVENTORY; i++)
+ for(i = 0; i < tsd->status.inventorySize; i++)
if (inventory2[i].nameid == inventory[n].nameid &&
inventory2[i].card[0] == inventory[n].card[0] && inventory2[i].card[1] == inventory[n].card[1] &&
inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) {
@@ -290,9 +298,9 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
}
}
- if (i == MAX_INVENTORY) {// look for an empty slot.
- for(i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);
- if (i == MAX_INVENTORY)
+ if (i == tsd->status.inventorySize) {// look for an empty slot.
+ for (i = 0; i < tsd->status.inventorySize && inventory2[i].nameid; i++);
+ if (i == tsd->status.inventorySize)
return 0;
memcpy(&inventory2[i], &inventory[n], sizeof(struct item));
inventory2[i].amount = amount;
@@ -303,13 +311,15 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
if (!amount)
continue;
n = tsd->deal.item[trade_i].index;
+ if (n < 0 || n >= tsd->status.inventorySize)
+ return 0;
if (amount > inventory2[n].amount)
return 0;
// search if it's possible to add item (for full inventory)
data = itemdb->search(inventory2[n].nameid);
- i = MAX_INVENTORY;
+ i = sd->status.inventorySize;
if (itemdb->isstackable2(data)) {
- for(i = 0; i < MAX_INVENTORY; i++)
+ for(i = 0; i < sd->status.inventorySize; i++)
if (inventory[i].nameid == inventory2[n].nameid &&
inventory[i].card[0] == inventory2[n].card[0] && inventory[i].card[1] == inventory2[n].card[1] &&
inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) {
@@ -320,9 +330,9 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
break;
}
}
- if (i == MAX_INVENTORY) {
- for(i = 0; i < MAX_INVENTORY && inventory[i].nameid; i++);
- if (i == MAX_INVENTORY)
+ if (i == sd->status.inventorySize) {
+ for(i = 0; i < sd->status.inventorySize && inventory[i].nameid; i++);
+ if (i == sd->status.inventorySize)
return 0;
memcpy(&inventory[i], &inventory2[n], sizeof(struct item));
inventory[i].amount = amount;
@@ -336,7 +346,8 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
/*==========================================
* Adds an item/qty to the trade window
*------------------------------------------*/
-void trade_tradeadditem(struct map_session_data *sd, short index, short amount) {
+static void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
+{
struct map_session_data *target_sd;
struct item *item;
int trade_i, trade_weight;
@@ -361,7 +372,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
index -= 2; // 0 is for zeny, 1 is unknown. Gravity, go figure...
//Item checks...
- if( index < 0 || index >= MAX_INVENTORY )
+ if (index < 0 || index >= sd->status.inventorySize)
return;
if( amount < 0 || amount > sd->status.inventory[index].amount )
return;
@@ -372,14 +383,14 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
if( !itemdb_cantrade(item, src_lv, dst_lv) && //Can't trade
(pc->get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade
{
- clif->message (sd->fd, msg_sd(sd,260));
+ clif->message (sd->fd, msg_sd(sd,260)); // This item cannot be traded.
clif->tradeitemok(sd, index+2, TIO_INDROCKS);
return;
}
if( item->expire_time )
{ // Rental System
- clif->message (sd->fd, msg_sd(sd,260));
+ clif->message (sd->fd, msg_sd(sd,260)); // This item cannot be traded.
clif->tradeitemok(sd, index+2, TIO_INDROCKS);
return;
}
@@ -388,7 +399,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
!( item->bound == IBT_GUILD && sd->status.guild_id == target_sd->status.guild_id ) &&
!( item->bound == IBT_PARTY && sd->status.party_id == target_sd->status.party_id )
&& !pc_can_give_bound_items(sd) ) {
- clif->message(sd->fd, msg_sd(sd,293));
+ clif->message(sd->fd, msg_sd(sd,293)); // This bound item cannot be traded to that character.
clif->tradeitemok(sd, index+2, TIO_INDROCKS);
return;
}
@@ -430,7 +441,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount)
/*==========================================
* Adds the specified amount of zeny to the trade window
*------------------------------------------*/
-void trade_tradeaddzeny(struct map_session_data* sd, int amount)
+static void trade_tradeaddzeny(struct map_session_data *sd, int amount)
{
struct map_session_data* target_sd;
nullpo_retv(sd);
@@ -456,9 +467,11 @@ void trade_tradeaddzeny(struct map_session_data* sd, int amount)
/*==========================================
* 'Ok' button on the trade window is pressed.
*------------------------------------------*/
-void trade_tradeok(struct map_session_data *sd) {
+static void trade_tradeok(struct map_session_data *sd)
+{
struct map_session_data *target_sd;
+ nullpo_retv(sd);
if(sd->state.deal_locked || !sd->state.trading)
return;
@@ -475,10 +488,12 @@ void trade_tradeok(struct map_session_data *sd) {
/*==========================================
* 'Cancel' is pressed. (or trade was force-canceled by the code)
*------------------------------------------*/
-void trade_tradecancel(struct map_session_data *sd) {
+static void trade_tradecancel(struct map_session_data *sd)
+{
struct map_session_data *target_sd;
int trade_i;
+ nullpo_retv(sd);
target_sd = map->id2sd(sd->trade_partner);
if(!sd->state.trading)
@@ -533,11 +548,13 @@ void trade_tradecancel(struct map_session_data *sd) {
/*==========================================
* lock sd and tsd trade data, execute the trade, clear, then save players
*------------------------------------------*/
-void trade_tradecommit(struct map_session_data *sd) {
+static void trade_tradecommit(struct map_session_data *sd)
+{
struct map_session_data *tsd;
int trade_i;
int flag;
+ nullpo_retv(sd);
if (!sd->state.trading || !sd->state.deal_locked) //Locked should be 1 (pressed ok) before you can press trade.
return;