Support itemids up to ~2 billion (#5141)
Co-authored-by: aleos89 <aleos89@users.noreply.github.com> Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
@@ -1606,7 +1606,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
int delete_amount = price, i;
|
||||
|
||||
if (!id) { // Item Data is checked at script parsing but in case of item_db reload, check again.
|
||||
ShowWarning("Failed to find sellitem %hu for itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y);
|
||||
ShowWarning("Failed to find sellitem %u for itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y);
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
if (cost[1] < points || cost[0] < (price - points)) {
|
||||
@@ -1614,7 +1614,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
|
||||
memset(output, '\0', sizeof(output));
|
||||
|
||||
sprintf(output, msg_txt(sd, 712), id->jname, id->nameid); // You do not have enough %s (%hu).
|
||||
sprintf(output, msg_txt(sd, 712), id->jname, id->nameid); // You do not have enough %s (%u).
|
||||
clif_messagecolor(&sd->bl, color_table[COLOR_RED], output, false, SELF);
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
@@ -1633,13 +1633,13 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
amount = delete_amount;
|
||||
|
||||
if (pc_delitem(sd, i, amount, 0, 0, LOG_TYPE_NPC)) {
|
||||
ShowWarning("Failed to delete item %hu from '%s' at itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, sd->status.name, nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y);
|
||||
ShowWarning("Failed to delete item %u from '%s' at itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, sd->status.name, nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y);
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
delete_amount -= amount;
|
||||
}
|
||||
if (delete_amount > 0) {
|
||||
ShowError("Item %hu is not enough as payment at itemshop NPC '%s' (%s, %d, %d, AID=%d, CID=%d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y, sd->status.account_id, sd->status.char_id);
|
||||
ShowError("Item %u is not enough as payment at itemshop NPC '%s' (%s, %d, %d, AID=%d, CID=%d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y, sd->status.account_id, sd->status.char_id);
|
||||
return ERROR_TYPE_PURCHASE_FAIL;
|
||||
}
|
||||
}
|
||||
@@ -1675,7 +1675,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub* item_list)
|
||||
{
|
||||
int i, j, amount, new_, w, vt;
|
||||
unsigned short nameid;
|
||||
t_itemid nameid;
|
||||
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
|
||||
enum e_CASHSHOP_ACK res;
|
||||
item_data *id;
|
||||
@@ -1707,7 +1707,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, str
|
||||
|
||||
if( !itemdb_isstackable2(id) && amount > 1 )
|
||||
{
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %hu!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
amount = item_list[i].amount = 1;
|
||||
}
|
||||
|
||||
@@ -1797,7 +1797,7 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in
|
||||
|
||||
memset(output, '\0', sizeof(output));
|
||||
|
||||
sprintf(output, msg_txt(sd, 714), id->jname, id->nameid); // Item Shop List: %s (%hu)
|
||||
sprintf(output, msg_txt(sd, 714), id->jname, id->nameid); // Item Shop List: %s (%u)
|
||||
clif_broadcast(&sd->bl, output, strlen(output) + 1, BC_BLUE,SELF);
|
||||
}
|
||||
|
||||
@@ -1833,7 +1833,7 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in
|
||||
* @param points: Cost of total items
|
||||
* @return clif_cashshop_ack value to display
|
||||
*/
|
||||
int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amount, int points)
|
||||
int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, int points)
|
||||
{
|
||||
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
|
||||
struct item_data *item;
|
||||
@@ -1865,7 +1865,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
|
||||
|
||||
if(!itemdb_isstackable2(item) && amount > 1)
|
||||
{
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %hu!\n",
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n",
|
||||
sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
amount = 1;
|
||||
}
|
||||
@@ -1886,7 +1886,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
|
||||
|
||||
if( (double)nd->u.shop.shop_item[i].value * amount > INT_MAX )
|
||||
{
|
||||
ShowWarning("npc_cashshop_buy: Item '%s' (%hu) price overflow attempt!\n", item->name, nameid);
|
||||
ShowWarning("npc_cashshop_buy: Item '%s' (%u) price overflow attempt!\n", item->name, nameid);
|
||||
ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n",
|
||||
nd->exname, map_mapid2mapname(nd->bl.m), nd->bl.x, nd->bl.y, sd->status.name, sd->status.account_id, sd->status.char_id, nd->u.shop.shop_item[i].value, amount);
|
||||
return ERROR_TYPE_ITEM_ID;
|
||||
@@ -1979,7 +1979,8 @@ uint8 npc_buylist(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *
|
||||
memset(market_index, 0, sizeof(market_index));
|
||||
// process entries in buy list, one by one
|
||||
for( i = 0; i < n; ++i ) {
|
||||
unsigned short nameid, amount;
|
||||
t_itemid nameid;
|
||||
unsigned short amount;
|
||||
int value;
|
||||
item_data *id;
|
||||
|
||||
@@ -2009,7 +2010,7 @@ uint8 npc_buylist(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *
|
||||
return 3; // item no longer in itemdb
|
||||
|
||||
if( !itemdb_isstackable2(id) && amount > 1 ) { //Exploit? You can't buy more than 1 of equipment types o.O
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %hu!\n",
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n",
|
||||
sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
amount = item_list[i].qty = 1;
|
||||
}
|
||||
@@ -2051,7 +2052,7 @@ uint8 npc_buylist(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *
|
||||
pc_payzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
|
||||
|
||||
for( i = 0; i < n; ++i ) {
|
||||
unsigned short nameid = item_list[i].nameid;
|
||||
t_itemid nameid = item_list[i].nameid;
|
||||
unsigned short amount = item_list[i].qty;
|
||||
|
||||
#if PACKETVER >= 20131223
|
||||
@@ -2201,7 +2202,7 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list
|
||||
// verify the sell list
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
unsigned short nameid;
|
||||
t_itemid nameid;
|
||||
int amount, idx, value;
|
||||
|
||||
idx = item_list[i*2]-2;
|
||||
@@ -2860,7 +2861,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
int m, is_discount = 0;
|
||||
uint16 dir;
|
||||
short x, y;
|
||||
unsigned short nameid = 0;
|
||||
t_itemid nameid = 0;
|
||||
struct npc_data *nd;
|
||||
enum npc_subtype type;
|
||||
|
||||
@@ -2904,12 +2905,12 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
|
||||
switch(type) {
|
||||
case NPCTYPE_ITEMSHOP: {
|
||||
if (sscanf(p,",%5hu:%11d,",&nameid,&is_discount) < 1) {
|
||||
if (sscanf(p,",%u:%11d,",&nameid,&is_discount) < 1) {
|
||||
ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
|
||||
return strchr(start,'\n'); // skip and continue
|
||||
}
|
||||
if (itemdb_exists(nameid) == NULL) {
|
||||
ShowWarning("npc_parse_shop: Invalid item ID cost in file '%s', line '%d' (id '%hu').\n", filepath, strline(buffer,start-buffer), nameid);
|
||||
ShowWarning("npc_parse_shop: Invalid item ID cost in file '%s', line '%d' (id '%u').\n", filepath, strline(buffer,start-buffer), nameid);
|
||||
return strchr(start,'\n'); // skip and continue
|
||||
}
|
||||
p = strchr(p+1,',');
|
||||
@@ -2964,7 +2965,8 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
nd = npc_create_npc(m, x, y);
|
||||
nd->u.shop.count = 0;
|
||||
while ( p ) {
|
||||
unsigned short nameid2, qty = 0;
|
||||
t_itemid nameid2;
|
||||
unsigned short qty = 0;
|
||||
int value;
|
||||
struct item_data* id;
|
||||
bool skip = false;
|
||||
@@ -2974,14 +2976,14 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
switch(type) {
|
||||
case NPCTYPE_MARKETSHOP:
|
||||
#if PACKETVER >= 20131223
|
||||
if (sscanf(p, ",%6hu:%11d:%6hu", &nameid2, &value, &qty) != 3) {
|
||||
if (sscanf(p, ",%u:%11d:%6hu", &nameid2, &value, &qty) != 3) {
|
||||
ShowError("npc_parse_shop: (MARKETSHOP) Invalid item definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer, start - buffer), w1, w2, w3, w4);
|
||||
skip = true;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
if (sscanf(p, ",%6hu:%11d", &nameid2, &value) != 2) {
|
||||
if (sscanf(p, ",%u:%11d", &nameid2, &value) != 2) {
|
||||
ShowError("npc_parse_shop: Invalid item definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer, start - buffer), w1, w2, w3, w4);
|
||||
skip = true;
|
||||
}
|
||||
@@ -2992,7 +2994,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
break;
|
||||
|
||||
if( (id = itemdb_exists(nameid2)) == NULL ) {
|
||||
ShowWarning("npc_parse_shop: Invalid sell item in file '%s', line '%d' (id '%hu').\n", filepath, strline(buffer,start-buffer), nameid2);
|
||||
ShowWarning("npc_parse_shop: Invalid sell item in file '%s', line '%d' (id '%u').\n", filepath, strline(buffer,start-buffer), nameid2);
|
||||
p = strchr(p+1,',');
|
||||
continue;
|
||||
}
|
||||
@@ -3001,15 +3003,15 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
else value = 0; // Cashshop doesn't have a "buy price" in the item_db
|
||||
}
|
||||
if (value == 0 && (type == NPCTYPE_SHOP || type == NPCTYPE_MARKETSHOP)) { // NPC selling items for free!
|
||||
ShowWarning("npc_parse_shop: Item %s [%hu] is being sold for FREE in file '%s', line '%d'.\n",
|
||||
ShowWarning("npc_parse_shop: Item %s [%u] is being sold for FREE in file '%s', line '%d'.\n",
|
||||
id->name, nameid2, filepath, strline(buffer,start-buffer));
|
||||
}
|
||||
if( type == NPCTYPE_SHOP && value*0.75 < id->value_sell*1.24 ) { // Exploit possible: you can buy and sell back with profit
|
||||
ShowWarning("npc_parse_shop: Item %s [%hu] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
|
||||
ShowWarning("npc_parse_shop: Item %s [%u] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
|
||||
id->name, nameid2, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer));
|
||||
}
|
||||
if (type == NPCTYPE_MARKETSHOP && (!qty || qty > UINT16_MAX)) {
|
||||
ShowWarning("npc_parse_shop: Item %s [%hu] is stocked with invalid value %d, changed to 1. File '%s', line '%d'.\n",
|
||||
ShowWarning("npc_parse_shop: Item %s [%u] is stocked with invalid value %d, changed to 1. File '%s', line '%d'.\n",
|
||||
id->name, nameid2, qty, filepath, strline(buffer,start-buffer));
|
||||
qty = 1;
|
||||
}
|
||||
@@ -3625,7 +3627,7 @@ int npc_instancedestroy(struct npc_data* nd)
|
||||
**/
|
||||
void npc_market_tosql(const char *exname, struct npc_item_list *list) {
|
||||
SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
|
||||
if (SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`name`,`nameid`,`price`,`amount`,`flag`) VALUES ('%s','%hu','%d','%hu','%" PRIu8 "')",
|
||||
if (SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`name`,`nameid`,`price`,`amount`,`flag`) VALUES ('%s','%u','%d','%hu','%" PRIu8 "')",
|
||||
market_table, exname, list->nameid, list->value, list->qty, list->flag) ||
|
||||
SQL_ERROR == SqlStmt_Execute(stmt))
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
@@ -3638,14 +3640,14 @@ void npc_market_tosql(const char *exname, struct npc_item_list *list) {
|
||||
* @param nameid Item ID
|
||||
* @param clear True: will removes all records related with the NPC
|
||||
**/
|
||||
void npc_market_delfromsql_(const char *exname, unsigned short nameid, bool clear) {
|
||||
void npc_market_delfromsql_(const char *exname, t_itemid nameid, bool clear) {
|
||||
SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
|
||||
if (clear) {
|
||||
if( SQL_ERROR == SqlStmt_Prepare(stmt, "DELETE FROM `%s` WHERE `name`='%s'", market_table, exname) ||
|
||||
SQL_ERROR == SqlStmt_Execute(stmt))
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
} else {
|
||||
if (SQL_ERROR == SqlStmt_Prepare(stmt, "DELETE FROM `%s` WHERE `name`='%s' AND `nameid`='%d' LIMIT 1", market_table, exname, nameid) ||
|
||||
if (SQL_ERROR == SqlStmt_Prepare(stmt, "DELETE FROM `%s` WHERE `name`='%s' AND `nameid`='%u' LIMIT 1", market_table, exname, nameid) ||
|
||||
SQL_ERROR == SqlStmt_Execute(stmt))
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
}
|
||||
@@ -3683,7 +3685,7 @@ static int npc_market_checkall_sub(DBKey key, DBData *data, va_list ap) {
|
||||
uint16 j;
|
||||
|
||||
if (!list->nameid || !itemdb_exists(list->nameid)) {
|
||||
ShowError("npc_market_checkall_sub: NPC '%s' sells invalid item '%hu', deleting...\n", nd->exname, list->nameid);
|
||||
ShowError("npc_market_checkall_sub: NPC '%s' sells invalid item '%u', deleting...\n", nd->exname, list->nameid);
|
||||
npc_market_delfromsql(nd->exname, list->nameid);
|
||||
continue;
|
||||
}
|
||||
@@ -3708,7 +3710,7 @@ static int npc_market_checkall_sub(DBKey key, DBData *data, va_list ap) {
|
||||
npc_market_tosql(nd->exname, &nd->u.shop.shop_item[j]);
|
||||
}
|
||||
else { // Removing "out-of-date" entry
|
||||
ShowError("npc_market_checkall_sub: NPC '%s' does not sell item %hu (qty %hu), deleting...\n", nd->exname, list->nameid, list->qty);
|
||||
ShowError("npc_market_checkall_sub: NPC '%s' does not sell item %u (qty %hu), deleting...\n", nd->exname, list->nameid, list->qty);
|
||||
npc_market_delfromsql(nd->exname, list->nameid);
|
||||
}
|
||||
}
|
||||
@@ -3771,7 +3773,7 @@ static void npc_market_fromsql(void) {
|
||||
strdb_put(NPCMarketDB, market->exname, market);
|
||||
}
|
||||
|
||||
Sql_GetData(mmysql_handle, 1, &data, NULL); list.nameid = atoi(data);
|
||||
Sql_GetData(mmysql_handle, 1, &data, NULL); list.nameid = strtoul(data, nullptr, 10);
|
||||
Sql_GetData(mmysql_handle, 2, &data, NULL); list.value = atoi(data);
|
||||
Sql_GetData(mmysql_handle, 3, &data, NULL); list.qty = atoi(data);
|
||||
Sql_GetData(mmysql_handle, 4, &data, NULL); list.flag = atoi(data);
|
||||
@@ -4250,7 +4252,7 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
|
||||
|
||||
if (!strcmpi(drop_arg1, "random"))
|
||||
args.nightmaredrop.drop_id = -1;
|
||||
else if (itemdb_exists((args.nightmaredrop.drop_id = atoi(drop_arg1))) == NULL) {
|
||||
else if (itemdb_exists((args.nightmaredrop.drop_id = strtol(drop_arg1, nullptr, 10))) == NULL) {
|
||||
args.nightmaredrop.drop_id = 0;
|
||||
ShowWarning("npc_parse_mapflag: Invalid item ID '%d' supplied for mapflag 'pvp_nightmaredrop' (file '%s', line '%d'), removing.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", args.nightmaredrop.drop_id, filepath, strline(buffer, start - buffer), w1, w2, w3, w4);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user