diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index 8b45b3f290..d1b2410cf4 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -1525,7 +1525,7 @@ 1370: Usage: ex. "@set PoringCharVarSTR$" outputs its value, Super Duper String. 1371: NPC variables may not be used with @set. 1372: Instance variables may not be used with @set. -1373: %s value is now: %d +1373: %s value is now: %lld 1374: %s value is now: %s 1375: %s is blank. diff --git a/conf/msg_conf/map_msg_chn.conf b/conf/msg_conf/map_msg_chn.conf index 765fc73181..f027b2aeeb 100644 --- a/conf/msg_conf/map_msg_chn.conf +++ b/conf/msg_conf/map_msg_chn.conf @@ -1341,8 +1341,8 @@ 1370: 用法: ex. "@set PoringCharVarSTR$" outputs its value, Super Duper String. 1371: NPC variables may not be used with @set. 1372: Instance variables may not be used with @set. -1373: %s value is now :%d -1374: %s value is now :%s +1373: %s value is now: %lld +1374: %s value is now: %s 1375: %s is empty //1376: free diff --git a/conf/msg_conf/map_msg_frn.conf b/conf/msg_conf/map_msg_frn.conf index 787aae67e4..e4c05ba42b 100644 --- a/conf/msg_conf/map_msg_frn.conf +++ b/conf/msg_conf/map_msg_frn.conf @@ -1354,8 +1354,8 @@ 1370: Usage: ex. "@set PoringCharVarSTR$" affiche sa valeur actuelle, Super Duper String. 1371: Les variables des NPC ne peuvent pas être utilisées/changées avec @set. 1372: Les variables d'Instance ne peuvent pas être utilisées avec @set. -1373: %s valeur est maintenant :%d -1374: %s valeur est maintenant :%s +1373: %s valeur est maintenant: %lld +1374: %s valeur est maintenant: %s 1375: %s est vide //1376: free diff --git a/conf/msg_conf/map_msg_idn.conf b/conf/msg_conf/map_msg_idn.conf index a238cedddd..080d7519cc 100644 --- a/conf/msg_conf/map_msg_idn.conf +++ b/conf/msg_conf/map_msg_idn.conf @@ -1445,7 +1445,7 @@ 1370: Contoh penggunaan: \"@set PoringCharVarSTR$\" menampilkan nilainya, Super Duper String. 1371: Variabel pada NPC tidak boleh digunakan dengan @set. 1372: Variabel instansi tidak boleh digunakan dengan @set. -1373: Nilai %s saat ini: %d +1373: Nilai %s saat ini: %lld 1374: Nilai %s saat ini: %s 1375: %s kosong //1376: free diff --git a/conf/msg_conf/map_msg_por.conf b/conf/msg_conf/map_msg_por.conf index 7391b74a41..2953f84f05 100644 --- a/conf/msg_conf/map_msg_por.conf +++ b/conf/msg_conf/map_msg_por.conf @@ -1524,8 +1524,8 @@ 1370: Uso: ex. "@set PoringCharVarSTR$" exibe seu valor, Super Duper String. 1371: Variáveis de NPC não podem ser usadas com @set. 1372: Variáveis de instância não podem ser usadas com @set. -1373: %s valor agora é :%d -1374: %s valor agora é :%s +1373: %s valor agora é: %lld +1374: %s valor agora é: %s 1375: %s é vazia //1376: free diff --git a/conf/msg_conf/map_msg_rus.conf b/conf/msg_conf/map_msg_rus.conf index 13b26a11ff..6526cec682 100644 --- a/conf/msg_conf/map_msg_rus.conf +++ b/conf/msg_conf/map_msg_rus.conf @@ -1354,8 +1354,8 @@ 1370: Èñïîëüçîâàíèå: ïðèì. "@set PoringCharVarSTR$" áóäåò èìåòü çíà÷åíèå "Super Duper String". 1371: Ïåðåìåííûå ÍÈÏ íå ìîãóò áûòü èñïîëüçîâàíû êîìàíäîé @set. 1372: Ïåðåìåííûå ãðóïï íå ìîãóò áûòü èñïîëüçîâàíû êîìàíäîé @set. -1373: %s çíà÷åíèå :%d -1374: %s çíà÷åíèå :%s +1373: %s çíà÷åíèå: %lld +1374: %s çíà÷åíèå: %s 1375: %s ïóñòî //1376: free diff --git a/conf/msg_conf/map_msg_spn.conf b/conf/msg_conf/map_msg_spn.conf index c9df8ca19e..3f5b9812bd 100644 --- a/conf/msg_conf/map_msg_spn.conf +++ b/conf/msg_conf/map_msg_spn.conf @@ -1493,7 +1493,7 @@ 1370: Instrucciones: ej. "@set PoringCharVarSTR$" muestra su valor, cadena de texto. 1371: Las variables de NPC no se pueden editar con @set. 1372: Las variables de instancias no se pueden editar con @set. -1373: El valor %s ahora es: %d +1373: El valor %s ahora es: %lld 1374: El valor %s ahora es: %s 1375: %s está vacío diff --git a/conf/msg_conf/map_msg_tha.conf b/conf/msg_conf/map_msg_tha.conf index 88b210ec75..a715149e9d 100644 --- a/conf/msg_conf/map_msg_tha.conf +++ b/conf/msg_conf/map_msg_tha.conf @@ -1347,7 +1347,7 @@ 1370: ÇÔ¸Õãªé: ex. "@set PoringCharVarSTR$" ¨ÐáÊ´§¼ÅÅѾ¸ìà»ç¹¤èÒ, Super Duper String. 1371: µÑÇá»Ã NPC äÁèÊÒÁÒöµÑ駤èÒä´é´éÇ @set ä´é. 1372: µÑÇá»Ã Instance äÁèÊÒÁÒöµÑ駤èÒä´é´éÇ @set ä´é. -1373: %s ÁÕ¤èÒ: %d +1373: %s ÁÕ¤èÒ: %lld 1374: %s ÁÕ¤èÒ: %s 1375: %s äÁèÁÕ¤èÒã´æ. //1376: free diff --git a/sql-files/main.sql b/sql-files/main.sql index 7123fce4b7..ab23488a65 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS `acc_reg_num` ( `account_id` int(11) unsigned NOT NULL default '0', `key` varchar(32) binary NOT NULL default '', `index` int(11) unsigned NOT NULL default '0', - `value` int(11) NOT NULL default '0', + `value` bigint(11) NOT NULL default '0', PRIMARY KEY (`account_id`,`key`,`index`), KEY `account_id` (`account_id`) ) ENGINE=MyISAM; @@ -274,7 +274,7 @@ CREATE TABLE IF NOT EXISTS `char_reg_num` ( `char_id` int(11) unsigned NOT NULL default '0', `key` varchar(32) binary NOT NULL default '', `index` int(11) unsigned NOT NULL default '0', - `value` int(11) NOT NULL default '0', + `value` bigint(11) NOT NULL default '0', PRIMARY KEY (`char_id`,`key`,`index`), KEY `char_id` (`char_id`) ) ENGINE=MyISAM; @@ -403,7 +403,7 @@ CREATE TABLE IF NOT EXISTS `global_acc_reg_num` ( `account_id` int(11) unsigned NOT NULL default '0', `key` varchar(32) binary NOT NULL default '', `index` int(11) unsigned NOT NULL default '0', - `value` int(11) NOT NULL default '0', + `value` bigint(11) NOT NULL default '0', PRIMARY KEY (`account_id`,`key`,`index`), KEY `account_id` (`account_id`) ) ENGINE=MyISAM; diff --git a/sql-files/upgrades/upgrade_20200109.sql b/sql-files/upgrades/upgrade_20200109.sql new file mode 100644 index 0000000000..3d7d6aad7f --- /dev/null +++ b/sql-files/upgrades/upgrade_20200109.sql @@ -0,0 +1,8 @@ +ALTER TABLE `acc_reg_num` + MODIFY `value` bigint(11) NOT NULL default '0'; + +ALTER TABLE `global_acc_reg_num` + MODIFY `value` bigint(11) NOT NULL default '0'; + +ALTER TABLE `char_reg_num` + MODIFY `value` bigint(11) NOT NULL default '0'; diff --git a/src/char/char_logif.cpp b/src/char/char_logif.cpp index dd967a7132..4e1630cb01 100644 --- a/src/char/char_logif.cpp +++ b/src/char/char_logif.cpp @@ -178,7 +178,7 @@ void chlogif_prepsend_global_accreg(void) { } } -void chlogif_send_global_accreg(const char *key, unsigned int index, intptr_t val, bool is_string) { +void chlogif_send_global_accreg(const char *key, unsigned int index, int64 int_value, const char* string_value, bool is_string) { int nlen = WFIFOW(login_fd, 2); size_t len; @@ -197,26 +197,25 @@ void chlogif_send_global_accreg(const char *key, unsigned int index, intptr_t va nlen += 4; if( is_string ) { - WFIFOB(login_fd, nlen) = val ? 2 : 3; + WFIFOB(login_fd, nlen) = string_value ? 2 : 3; nlen += 1; - if( val ) { - char *sval = (char*)val; - len = strlen(sval)+1; + if( string_value ) { + len = strlen(string_value)+1; WFIFOB(login_fd, nlen) = (unsigned char)len; // won't be higher; the column size is 254 nlen += 1; - safestrncpy(WFIFOCP(login_fd,nlen), sval, len); + safestrncpy(WFIFOCP(login_fd,nlen), string_value, len); nlen += len; } } else { - WFIFOB(login_fd, nlen) = val ? 0 : 1; + WFIFOB(login_fd, nlen) = int_value ? 0 : 1; nlen += 1; - if( val ) { - WFIFOL(login_fd, nlen) = (int)val; - nlen += 4; + if( int_value ) { + WFIFOQ(login_fd, nlen) = int_value; + nlen += 8; } } diff --git a/src/char/char_logif.hpp b/src/char/char_logif.hpp index 7c6bb543f3..721ab4e58e 100644 --- a/src/char/char_logif.hpp +++ b/src/char/char_logif.hpp @@ -19,7 +19,7 @@ TIMER_FUNC(chlogif_broadcast_user_count); void chlogif_send_usercount(int users); void chlogif_upd_global_accreg(uint32 account_id, uint32 char_id); void chlogif_prepsend_global_accreg(void); -void chlogif_send_global_accreg(const char *key, unsigned int index, intptr_t val, bool is_string); +void chlogif_send_global_accreg(const char *key, unsigned int index, int64 int_value, const char* string_value, bool is_string); void chlogif_request_accreg2(uint32 account_id, uint32 char_id); void chlogif_send_reqaccdata(int fd, struct char_session_data *sd); void chlogif_send_setacconline(int aid); diff --git a/src/char/inter.cpp b/src/char/inter.cpp index a0e96602a7..b38e7bb8e9 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -561,54 +561,54 @@ void mapif_accinfo_ack(bool success, int map_fd, int u_fd, int u_aid, int accoun * @param val either str or int, depending on type * @param type false when int, true otherwise **/ -void inter_savereg(uint32 account_id, uint32 char_id, const char *key, unsigned int index, intptr_t val, bool is_string) +void inter_savereg(uint32 account_id, uint32 char_id, const char *key, uint32 index, int64 int_value, const char* string_value, bool is_string) { char esc_val[254*2+1]; char esc_key[32*2+1]; Sql_EscapeString(sql_handle, esc_key, key); - if( is_string && val ) { - Sql_EscapeString(sql_handle, esc_val, (char*)val); + if( is_string && string_value ) { + Sql_EscapeString(sql_handle, esc_val, string_value); } if( key[0] == '#' && key[1] == '#' ) { // global account reg if( session_isValid(login_fd) ) - chlogif_send_global_accreg(key,index,val,is_string); + chlogif_send_global_accreg( key, index, int_value, string_value, is_string ); else { - ShowError("Login server unavailable, can't perform update on '%s' variable for AID:%d CID:%d\n",key,account_id,char_id); + ShowError("Login server unavailable, can't perform update on '%s' variable for AID:%" PRIu32 " CID:%" PRIu32 "\n",key,account_id,char_id); } } else if ( key[0] == '#' ) { // local account reg if( is_string ) { - if( val ) { - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", schema_config.acc_reg_str_table, account_id, esc_key, index, esc_val) ) + if( string_value ) { + if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%" PRIu32 "','%s','%" PRIu32 "','%s')", schema_config.acc_reg_str_table, account_id, esc_key, index, esc_val) ) Sql_ShowDebug(sql_handle); } else { - if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", schema_config.acc_reg_str_table, account_id, esc_key, index) ) + if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%" PRIu32 "' AND `key` = '%s' AND `index` = '%" PRIu32 "' LIMIT 1", schema_config.acc_reg_str_table, account_id, esc_key, index) ) Sql_ShowDebug(sql_handle); } } else { - if( val ) { - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", schema_config.acc_reg_num_table, account_id, esc_key, index, (int)val) ) + if( int_value ) { + if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%" PRIu32 "','%s','%" PRIu32 "','%" PRId64 "')", schema_config.acc_reg_num_table, account_id, esc_key, index, int_value) ) Sql_ShowDebug(sql_handle); } else { - if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", schema_config.acc_reg_num_table, account_id, esc_key, index) ) + if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%" PRIu32 "' AND `key` = '%s' AND `index` = '%" PRIu32 "' LIMIT 1", schema_config.acc_reg_num_table, account_id, esc_key, index) ) Sql_ShowDebug(sql_handle); } } } else { /* char reg */ if( is_string ) { - if( val ) { - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", schema_config.char_reg_str_table, char_id, esc_key, index, esc_val) ) + if( string_value ) { + if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%" PRIu32 "','%s','%" PRIu32 "','%s')", schema_config.char_reg_str_table, char_id, esc_key, index, esc_val) ) Sql_ShowDebug(sql_handle); } else { - if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", schema_config.char_reg_str_table, char_id, esc_key, index) ) + if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%" PRIu32 "' AND `key` = '%s' AND `index` = '%" PRIu32 "' LIMIT 1", schema_config.char_reg_str_table, char_id, esc_key, index) ) Sql_ShowDebug(sql_handle); } } else { - if( val ) { - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", schema_config.char_reg_num_table, char_id, esc_key, index, (int)val) ) + if( int_value ) { + if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%" PRIu32 "','%s','%" PRIu32 "','%" PRId64 "')", schema_config.char_reg_num_table, char_id, esc_key, index, int_value) ) Sql_ShowDebug(sql_handle); } else { - if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", schema_config.char_reg_num_table, char_id, esc_key, index) ) + if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%" PRIu32 "' AND `key` = '%s' AND `index` = '%" PRIu32 "' LIMIT 1", schema_config.char_reg_num_table, char_id, esc_key, index) ) Sql_ShowDebug(sql_handle); } } @@ -624,11 +624,11 @@ int inter_accreg_fromsql(uint32 account_id, uint32 char_id, int fd, int type) switch( type ) { case 3: //char reg - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", schema_config.char_reg_str_table, char_id) ) + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%" PRIu32 "'", schema_config.char_reg_str_table, char_id) ) Sql_ShowDebug(sql_handle); break; case 2: //account reg - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", schema_config.acc_reg_str_table, account_id) ) + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%" PRIu32 "'", schema_config.acc_reg_str_table, account_id) ) Sql_ShowDebug(sql_handle); break; case 1: //account2 reg @@ -667,7 +667,7 @@ int inter_accreg_fromsql(uint32 account_id, uint32 char_id, int fd, int type) Sql_GetData(sql_handle, 1, &data, NULL); - WFIFOL(fd, plen) = (unsigned int)atol(data); + WFIFOL(fd, plen) = (uint32)atol(data); plen += 4; Sql_GetData(sql_handle, 2, &data, NULL); @@ -705,11 +705,11 @@ int inter_accreg_fromsql(uint32 account_id, uint32 char_id, int fd, int type) switch( type ) { case 3: //char reg - if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", schema_config.char_reg_num_table, char_id)) + if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%" PRIu32 "'", schema_config.char_reg_num_table, char_id)) Sql_ShowDebug(sql_handle); break; case 2: //account reg - if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", schema_config.acc_reg_num_table, account_id)) + if (SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%" PRIu32 "'", schema_config.acc_reg_num_table, account_id)) Sql_ShowDebug(sql_handle); break; #if 0 // This is already checked above. @@ -747,13 +747,13 @@ int inter_accreg_fromsql(uint32 account_id, uint32 char_id, int fd, int type) Sql_GetData(sql_handle, 1, &data, NULL); - WFIFOL(fd, plen) = (unsigned int)atol(data); + WFIFOL(fd, plen) = (uint32)atol(data); plen += 4; Sql_GetData(sql_handle, 2, &data, NULL); - WFIFOL(fd, plen) = atoi(data); - plen += 4; + WFIFOQ(fd, plen) = strtoll(data,NULL,10); + plen += 8; WFIFOW(fd, 14) += 1; @@ -1258,7 +1258,8 @@ int mapif_parse_WisToGM(int fd) // Save account_reg into sql (type=2) int mapif_parse_Registry(int fd) { - int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12); + uint32 account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8); + uint16 count = RFIFOW(fd, 12); if( count ) { int cursor = 14, i; @@ -1273,20 +1274,17 @@ int mapif_parse_Registry(int fd) std::string key( src_key, lenkey ); cursor += lenkey + 1; - unsigned int index = RFIFOL(fd, cursor); + uint32 index = RFIFOL(fd, cursor); cursor += 4; switch (RFIFOB(fd, cursor++)) { // int case 0: - { - intptr_t lVal = RFIFOL( fd, cursor ); - inter_savereg( account_id, char_id, key.c_str(), index, lVal, false ); - cursor += 4; + inter_savereg( account_id, char_id, key.c_str(), index, RFIFOQ( fd, cursor ), nullptr, false ); + cursor += 8; break; - } case 1: - inter_savereg(account_id,char_id,key.c_str(),index,0,false); + inter_savereg( account_id, char_id, key.c_str(), index, 0, nullptr, false ); break; // str case 2: @@ -1295,11 +1293,11 @@ int mapif_parse_Registry(int fd) const char* src_val= RFIFOCP(fd, cursor + 1); std::string sval( src_val, len_val ); cursor += len_val + 1; - inter_savereg( account_id, char_id, key.c_str(), index, (intptr_t)sval.c_str(), true ); + inter_savereg( account_id, char_id, key.c_str(), index, 0, sval.c_str(), true ); break; } case 3: - inter_savereg(account_id,char_id,key.c_str(),index,0,true); + inter_savereg( account_id, char_id, key.c_str(), index, 0, nullptr, true ); break; default: ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1)); diff --git a/src/char/inter.hpp b/src/char/inter.hpp index 2d7a562903..d054b3ccc1 100644 --- a/src/char/inter.hpp +++ b/src/char/inter.hpp @@ -42,7 +42,6 @@ extern unsigned int party_share_level; extern Sql* sql_handle; extern Sql* lsql_handle; -void inter_savereg(uint32 account_id, uint32 char_id, const char *key, unsigned int index, intptr_t val, bool is_string); int inter_accreg_fromsql(uint32 account_id, uint32 char_id, int fd, int type); #endif /* INTER_HPP */ diff --git a/src/common/db.cpp b/src/common/db.cpp index 14ca951ed7..b445481b20 100644 --- a/src/common/db.cpp +++ b/src/common/db.cpp @@ -2707,6 +2707,22 @@ DBData db_ptr2data(void *data) return ret; } +/** + * Manual cast from 'int' to the struct DBData. + * @param data Data to be casted + * @return The data as a DBData struct + * @public + */ +DBData db_i642data(int64 data) +{ + DBData ret; + + DB_COUNTSTAT(db_i2data); + ret.type = DB_DATA_I64; + ret.u.i64 = data; + return ret; +} + /** * Gets int type data from struct DBData. * If data is not int type, returns 0. @@ -2752,6 +2768,21 @@ void* db_data2ptr(DBData *data) return NULL; } +/** + * Gets int64 type data from struct DBData. + * If data is not int64 type, returns 0. + * @param data Data + * @return Integer(64-bit signed) value of the data. + * @public + */ +int64 db_data2i64(DBData *data) +{ + DB_COUNTSTAT(db_data2i64); + if (data && DB_DATA_I64 == data->type) + return data->u.i64; + return 0; +} + /** * Initializes the database system. * @public diff --git a/src/common/db.hpp b/src/common/db.hpp index 4d48bd47f0..dd5fd73da3 100644 --- a/src/common/db.hpp +++ b/src/common/db.hpp @@ -167,6 +167,7 @@ typedef enum DBDataType { DB_DATA_INT, DB_DATA_UINT, DB_DATA_PTR, + DB_DATA_I64 } DBDataType; /** @@ -176,6 +177,7 @@ typedef enum DBDataType { * @param u.i Data of int type * @param u.ui Data of unsigned int type * @param u.ptr Data of void* type + * @param u.i64 Data of int64 type * @public */ typedef struct DBData { @@ -184,6 +186,7 @@ typedef struct DBData { int i; unsigned int ui; void *ptr; + int64 i64; } u; } DBData; @@ -638,6 +641,14 @@ struct DBMap { #define i64db_uiget(db,k) ( db_data2ui((db)->get((db),db_i642key(k))) ) #define ui64db_uiget(db,k) ( db_data2ui((db)->get((db),db_ui642key(k))) ) +// Get int64-type data from DBMaps of various key types +#define db_i64get(db,k) ( db_data2i64((db)->get((db),(k))) ) +#define idb_i64get(db,k) ( db_data2i64((db)->get((db),db_i2key(k))) ) +#define uidb_i64get(db,k) ( db_data2i64((db)->get((db),db_ui2key(k))) ) +#define strdb_i64get(db,k) ( db_data2i64((db)->get((db),db_str2key(k))) ) +#define i64db_i64get(db,k) ( db_data2i64((db)->get((db),db_i642key(k))) ) +#define ui64db_i64get(db,k) ( db_data2i64((db)->get((db),db_ui642key(k))) ) + // Put pointer-type data into DBMaps of various key types #define db_put(db,k,d) ( (db)->put((db),(k),db_ptr2data(d),NULL) ) #define idb_put(db,k,d) ( (db)->put((db),db_i2key(k),db_ptr2data(d),NULL) ) @@ -662,6 +673,14 @@ struct DBMap { #define i64db_uiput(db,k,d) ( (db)->put((db),db_i642key(k),db_ui2data(d),NULL) ) #define ui64db_uiput(db,k,d) ( (db)->put((db),db_ui642key(k),db_ui2data(d),NULL) ) +// Put int64 data into DBMaps of various key types +#define db_i64put(db,k,d) ( (db)->put((db),(k),db_i642data(d),NULL) ) +#define idb_i64put(db,k,d) ( (db)->put((db),db_i2key(k),db_i642data(d),NULL) ) +#define uidb_i64put(db,k,d) ( (db)->put((db),db_ui2key(k),db_i642data(d),NULL) ) +#define strdb_i64put(db,k,d) ( (db)->put((db),db_str2key(k),db_i642data(d),NULL) ) +#define i64db_i64put(db,k,d) ( (db)->put((db),db_i642key(k),db_i642data(d),NULL) ) +#define ui64db_i64put(db,k,d) ( (db)->put((db),db_ui642key(k),db_i642data(d),NULL) ) + // Remove entry from DBMaps of various key types #define db_remove(db,k) ( (db)->remove((db),(k),NULL) ) #define idb_remove(db,k) ( (db)->remove((db),db_i2key(k),NULL) ) @@ -872,6 +891,14 @@ DBData db_ui2data(unsigned int data); */ DBData db_ptr2data(void *data); +/** + * Manual cast from 'int64' to the struct DBData. + * @param data Data to be casted + * @return The data as a DBData struct + * @public + */ +DBData db_i642data(int64 data); + /** * Gets int type data from struct DBData. * If data is not int type, returns 0. @@ -899,6 +926,15 @@ unsigned int db_data2ui(DBData *data); */ void* db_data2ptr(DBData *data); +/** + * Gets int64 type data from struct DBData. + * If data is not int64 type, returns 0. + * @param data Data + * @return Integer(64-bit signed) value of the data. + * @public + */ +int64 db_data2i64(DBData *data); + /** * Initialize the database system. * @public diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index c44f22555c..5431606fec 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -322,7 +322,7 @@ struct script_reg_state { struct script_reg_num { struct script_reg_state flag; - int value; + int64 value; }; struct script_reg_str { diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp index de7db772fc..3023743e33 100644 --- a/src/common/utilities.cpp +++ b/src/common/utilities.cpp @@ -64,3 +64,71 @@ int levenshtein(const std::string &s1, const std::string &s2) delete[] column; return result; } + +bool rathena::util::safe_addition( int64 a, int64 b, int64& result ){ +#if defined(__GNUC__) || defined(__clang__) + return __builtin_add_overflow( a, b, &result ); +#else + bool overflow = false; + + if( b < 0 ){ + if( a < ( INT64_MIN - b ) ){ + overflow = true; + } + }else{ + if( a > ( INT64_MAX - b ) ){ + overflow = true; + } + } + + result = a + b; + + return overflow; +#endif +} + +bool rathena::util::safe_substraction( int64 a, int64 b, int64& result ){ +#if defined(__GNUC__) || defined(__clang__) + return __builtin_sub_overflow( a, b, &result ); +#else + bool overflow = false; + + if( b < 0 ){ + if( a > ( INT64_MAX + b ) ){ + overflow = true; + } + }else{ + if( a < ( INT64_MIN + b ) ){ + overflow = true; + } + } + + result = a - b; + + return overflow; +#endif +} + +bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){ +#if defined(__GNUC__) || defined(__clang__) + return __builtin_mul_overflow( a, b, &result ); +#else + result = a * b; + + if( a > 0 ){ + if( b > 0 ){ + return result < 0; + }else if( b < 0 ){ + return result > 0; + } + }else if( a < 0 ){ + if( b > 0 ){ + return result > 0; + }else if( b < 0 ){ + return result < 0; + } + } + + return false; +#endif +} diff --git a/src/common/utilities.hpp b/src/common/utilities.hpp index 70d0200f8e..86afafe88b 100644 --- a/src/common/utilities.hpp +++ b/src/common/utilities.hpp @@ -134,6 +134,10 @@ namespace rathena { return it->second; } + + bool safe_addition( int64 a, int64 b, int64& result ); + bool safe_substraction( int64 a, int64 b, int64& result ); + bool safe_multiplication( int64 a, int64 b, int64& result ); } } diff --git a/src/login/account.cpp b/src/login/account.cpp index 73b625ada3..522bdb6e40 100644 --- a/src/login/account.cpp +++ b/src/login/account.cpp @@ -641,17 +641,17 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo return result; } -void mmo_save_global_accreg(AccountDB* self, int fd, int account_id, int char_id) { +void mmo_save_global_accreg(AccountDB* self, int fd, uint32 account_id, uint32 char_id) { Sql* sql_handle = ((AccountDB_SQL*)self)->accounts; AccountDB_SQL* db = (AccountDB_SQL*)self; - int count = RFIFOW(fd, 12); + uint16 count = RFIFOW(fd, 12); if (count) { int cursor = 14, i; char key[32], sval[254], esc_key[32*2+1], esc_sval[254*2+1]; for (i = 0; i < count; i++) { - unsigned int index; + uint32 index; safestrncpy(key, RFIFOCP(fd, cursor + 1), RFIFOB(fd, cursor)); Sql_EscapeString(sql_handle, esc_key, key); cursor += RFIFOB(fd, cursor) + 1; @@ -662,12 +662,12 @@ void mmo_save_global_accreg(AccountDB* self, int fd, int account_id, int char_id switch (RFIFOB(fd, cursor++)) { // int case 0: - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", db->global_acc_reg_num_table, account_id, esc_key, index, RFIFOL(fd, cursor)) ) + if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%" PRIu32 "','%s','%" PRIu32 "','%" PRId64 "')", db->global_acc_reg_num_table, account_id, esc_key, index, RFIFOQ(fd, cursor)) ) Sql_ShowDebug(sql_handle); - cursor += 4; + cursor += 8; break; case 1: - if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_num_table, account_id, esc_key, index) ) + if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%" PRIu32 "' AND `key` = '%s' AND `index` = '%" PRIu32 "' LIMIT 1", db->global_acc_reg_num_table, account_id, esc_key, index) ) Sql_ShowDebug(sql_handle); break; // str @@ -675,11 +675,11 @@ void mmo_save_global_accreg(AccountDB* self, int fd, int account_id, int char_id safestrncpy(sval, RFIFOCP(fd, cursor + 1), RFIFOB(fd, cursor)); cursor += RFIFOB(fd, cursor) + 1; Sql_EscapeString(sql_handle, esc_sval, sval); - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_table, account_id, esc_key, index, esc_sval) ) + if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%" PRIu32 "','%s','%" PRIu32 "','%s')", db->global_acc_reg_str_table, account_id, esc_key, index, esc_sval) ) Sql_ShowDebug(sql_handle); break; case 3: - if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_str_table, account_id, esc_key, index) ) + if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%" PRIu32 "' AND `key` = '%s' AND `index` = '%" PRIu32 "' LIMIT 1", db->global_acc_reg_str_table, account_id, esc_key, index) ) Sql_ShowDebug(sql_handle); break; default: @@ -690,14 +690,14 @@ void mmo_save_global_accreg(AccountDB* self, int fd, int account_id, int char_id } } -void mmo_send_global_accreg(AccountDB* self, int fd, int account_id, int char_id) { +void mmo_send_global_accreg(AccountDB* self, int fd, uint32 account_id, uint32 char_id) { Sql* sql_handle = ((AccountDB_SQL*)self)->accounts; AccountDB_SQL* db = (AccountDB_SQL*)self; char* data; int plen = 0; size_t len; - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_str_table, account_id) ) + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%" PRIu32 "'", db->global_acc_reg_str_table, account_id) ) Sql_ShowDebug(sql_handle); WFIFOHEAD(fd, 60000 + 300); @@ -728,7 +728,7 @@ void mmo_send_global_accreg(AccountDB* self, int fd, int account_id, int char_id Sql_GetData(sql_handle, 1, &data, NULL); - WFIFOL(fd, plen) = (unsigned int)atol(data); + WFIFOL(fd, plen) = (uint32)atol(data); plen += 4; Sql_GetData(sql_handle, 2, &data, NULL); @@ -764,7 +764,7 @@ void mmo_send_global_accreg(AccountDB* self, int fd, int account_id, int char_id Sql_FreeResult(sql_handle); - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_num_table, account_id) ) + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%" PRIu32 "'", db->global_acc_reg_num_table, account_id) ) Sql_ShowDebug(sql_handle); WFIFOHEAD(fd, 60000 + 300); @@ -795,13 +795,13 @@ void mmo_send_global_accreg(AccountDB* self, int fd, int account_id, int char_id Sql_GetData(sql_handle, 1, &data, NULL); - WFIFOL(fd, plen) = (unsigned int)atol(data); + WFIFOL(fd, plen) = (uint32)atol(data); plen += 4; Sql_GetData(sql_handle, 2, &data, NULL); - WFIFOL(fd, plen) = atoi(data); - plen += 4; + WFIFOQ(fd, plen) = strtoll(data,NULL,10); + plen += 8; WFIFOW(fd, 14) += 1; diff --git a/src/login/account.hpp b/src/login/account.hpp index bc9c6f3d7c..65ef0b2fa2 100644 --- a/src/login/account.hpp +++ b/src/login/account.hpp @@ -132,7 +132,7 @@ struct AccountDB { AccountDBIterator* (*iterator)(AccountDB* self); }; -void mmo_send_global_accreg(AccountDB* self, int fd, int account_id, int char_id); -void mmo_save_global_accreg(AccountDB* self, int fd, int account_id, int char_id); +void mmo_send_global_accreg(AccountDB* self, int fd, uint32 account_id, uint32 char_id); +void mmo_save_global_accreg(AccountDB* self, int fd, uint32 account_id, uint32 char_id); #endif /* ACCOUNT_HPP */ diff --git a/src/map/achievement.cpp b/src/map/achievement.cpp index ced4045d81..66ea1fdf1f 100644 --- a/src/map/achievement.cpp +++ b/src/map/achievement.cpp @@ -77,7 +77,7 @@ uint64 AchievementDatabase::parseBodyNode(const YAML::Node &node){ return 0; } - int constant; + int64 constant; if( !script_get_constant( group_name.c_str(), &constant ) ){ this->invalidWarning( node, "achievement_read_db_sub: Invalid group %s for achievement %d, skipping.\n", group_name.c_str(), achievement_id ); diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 0adad2095d..4ba9813d73 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -9259,7 +9259,8 @@ ACMD_FUNC(accinfo) { */ ACMD_FUNC(set) { char reg[46], val[128], name[32]; - int toset = 0, len, index; + int toset = 0, len; + uint32 index; bool is_str = false; int64 uid; @@ -9281,7 +9282,7 @@ ACMD_FUNC(set) { } // Check if the user wanted to set an array - if( sscanf( reg, "%31[^[][%11d]", name, &index ) < 2 ){ + if( sscanf( reg, "%31[^[][%" PRIu32 "]", name, &index ) < 2 ){ // The user did not specify array brackets, so we set the index to zero index = 0; } @@ -9297,7 +9298,11 @@ ACMD_FUNC(set) { // Only set the variable if there is a value for it if( toset >= 2 ){ - setd_sub( NULL, sd, name, index, is_str ? (void*)val : (void*)__64BPRTSIZE((atoi(val))), NULL ); + if( is_str ){ + setd_sub_str( NULL, sd, name, index, val, NULL ); + }else{ + setd_sub_num( NULL, sd, name, index, strtoll( val, NULL, 10 ), NULL ); + } } uid = reference_uid( add_str( name ), index ); @@ -9326,10 +9331,10 @@ ACMD_FUNC(set) { if( value == NULL || *value == '\0' ){// empty string sprintf(atcmd_output,msg_txt(sd,1375),reg); // %s is empty }else{ - sprintf(atcmd_output,msg_txt(sd,1374),reg,value); // %s value is now :%s + sprintf(atcmd_output,msg_txt(sd,1374),reg,value); // %s value is now: %s } } else {// integer variable - int value; + int64 value; switch( reg[0] ) { case '@': @@ -9349,7 +9354,7 @@ ACMD_FUNC(set) { break; } - sprintf(atcmd_output,msg_txt(sd,1373),reg,value); // %s value is now :%d + sprintf(atcmd_output,msg_txt(sd,1373),reg,value); // %s value is now: %lld } clif_displaymessage(fd, atcmd_output); diff --git a/src/map/channel.cpp b/src/map/channel.cpp index fee78b6b57..f1cd241019 100644 --- a/src/map/channel.cpp +++ b/src/map/channel.cpp @@ -1320,7 +1320,8 @@ bool channel_read_sub(config_setting_t *chan, struct Channel *tmp_chan, uint8 i) config_setting_t *group_list = NULL; int delay = 1000, autojoin = 0, leave = 1, chat = 1, color_override = 0, self_notif = 1, join_notif = 0, leave_notif = 0; - int type = CHAN_TYPE_PUBLIC, group_count = 0; + int64 type = CHAN_TYPE_PUBLIC; + int group_count = 0; const char *name = NULL, *password = NULL, *alias = NULL, *color_str = "Default", *type_str = NULL; if (tmp_chan == NULL) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 6ce1c03c4a..898912b9b9 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -11362,7 +11362,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) for( i = 0; i < NUM_WHISPER_VAR; ++i ) { char variablename[CHAT_SIZE_MAX]; safesnprintf(variablename,sizeof(variablename),"@whispervar%d$", i); - set_var(sd,variablename,(char *) split_data[i]); + set_var_str( sd, variablename, split_data[i] ); } safesnprintf(event,sizeof(event),"%s::%s", npc->exname,script_config.onwhisper_event_name); diff --git a/src/map/duel.cpp b/src/map/duel.cpp index 321a55c0ff..912b3772ce 100644 --- a/src/map/duel.cpp +++ b/src/map/duel.cpp @@ -63,7 +63,7 @@ void duel_savetime(struct map_session_data* sd) */ bool duel_checktime(struct map_session_data* sd) { - int diff; + int64 diff; time_t timer; struct tm *t; diff --git a/src/map/intif.cpp b/src/map/intif.cpp index dd61e29916..3f15c5e3cc 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -479,8 +479,8 @@ int intif_saveregistry(struct map_session_data *sd) plen += 1; if( p->value ) { - WFIFOL(inter_fd, plen) = p->value; - plen += 4; + WFIFOQ(inter_fd, plen) = p->value; + plen += 8; } else { script_reg_destroy_single(sd,key.i64,&p->flag); } @@ -1407,7 +1407,7 @@ void intif_parse_Registers(int fd) if( RFIFOW(fd, 14) ) { char key[32]; - unsigned int index; + uint32 index; int max = RFIFOW(fd, 14), cursor = 16, i; /** @@ -1428,7 +1428,7 @@ void intif_parse_Registers(int fd) safestrncpy(sval, RFIFOCP(fd, cursor + 1), RFIFOB(fd, cursor)); cursor += RFIFOB(fd, cursor) + 1; - set_reg(NULL,sd,reference_uid(add_str(key), index), key, (void*)sval, NULL); + set_reg_str( NULL, sd, reference_uid( add_str( key ), index ), key, sval, NULL ); } /** * Vessel! @@ -1438,17 +1438,17 @@ void intif_parse_Registers(int fd) **/ } else { for(i = 0; i < max; i++) { - int ival; + int64 ival; safestrncpy(key, RFIFOCP(fd, cursor + 1), RFIFOB(fd, cursor)); cursor += RFIFOB(fd, cursor) + 1; index = RFIFOL(fd, cursor); cursor += 4; - ival = RFIFOL(fd, cursor); - cursor += 4; + ival = RFIFOQ(fd, cursor); + cursor += 8; - set_reg(NULL,sd,reference_uid(add_str(key), index), key, (void*)__64BPRTSIZE(ival), NULL); + set_reg_num( NULL, sd, reference_uid( add_str( key ), index ), key, ival, NULL ); } } } diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 54549969af..b7e5525972 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -634,8 +634,14 @@ static bool itemdb_read_group(char* str[], int columns, int current) { if( ISDIGIT(str[0][0]) ){ group_id = atoi(str[0]); }else{ + int64 group_tmp; + // Try to parse group id as constant - script_get_constant(str[0], &group_id); + if (!script_get_constant(str[0], &group_tmp)) { + ShowError("itemdb_read_group: Unknown group constant \"%s\".\n", str[0]); + return false; + } + group_id = static_cast(group_tmp); } // Check the group id @@ -830,7 +836,7 @@ static bool itemdb_read_itemdelay(char* str[], int columns, int current) { else if( ISDIGIT(str[2][0]) ) id->delay_sc = atoi(str[2]); else{ // Try read sc group id from const db - int constant; + int64 constant; if( !script_get_constant(trim(str[2]), &constant) ){ ShowWarning("itemdb_read_itemdelay: Invalid sc group \"%s\" for item id %hu.\n", str[2], nameid); @@ -1707,7 +1713,13 @@ static bool itemdb_read_randomopt(const char* basedir, bool silent) { id = atoi(str[0]); } else { - script_get_constant(str[0], &id); + int64 id_tmp; + + if (!script_get_constant(str[0], &id_tmp)) { + ShowError("itemdb_read_randopt: Unknown random option constant \"%s\".\n", str[0]); + continue; + } + id = static_cast(id_tmp); } if (id < 0) { @@ -1769,15 +1781,19 @@ struct s_random_opt_group *itemdb_randomopt_group_exists(int id) { * @author [Cydh] **/ static bool itemdb_read_randomopt_group(char* str[], int columns, int current) { - int id = 0, i; + int64 id_tmp; + int id = 0; + int i; unsigned short rate = (unsigned short)strtoul(str[1], NULL, 10); struct s_random_opt_group *g = NULL; - if (!script_get_constant(str[0], &id)) { + if (!script_get_constant(str[0], &id_tmp)) { ShowError("itemdb_read_randomopt_group: Invalid ID for Random Option Group '%s'.\n", str[0]); return false; } + id = static_cast(id_tmp); + if ((columns-2)%3 != 0) { ShowError("itemdb_read_randomopt_group: Invalid column entries '%d'.\n", columns); return false; @@ -1797,8 +1813,10 @@ static bool itemdb_read_randomopt_group(char* str[], int columns, int current) { int j, k; memset(&g->entries[i].option, 0, sizeof(g->entries[i].option)); for (j = 0, k = 2; k < columns && j < MAX_ITEM_RDM_OPT; k+=3) { + int64 randid_tmp; int randid = 0; - if (!script_get_constant(str[k], &randid) || !itemdb_randomopt_exists(randid)) { + + if (!script_get_constant(str[k], &randid_tmp) || ((randid = static_cast(randid_tmp)) && !itemdb_randomopt_exists(randid))) { ShowError("itemdb_read_randomopt_group: Invalid random group id '%s' in column %d!\n", str[k], k+1); continue; } diff --git a/src/map/map.cpp b/src/map/map.cpp index e41a6c3c2f..47bfbeea80 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -4517,7 +4517,7 @@ static int map_mapflag_pvp_stop_sub(struct block_list *bl, va_list ap) enum e_mapflag map_getmapflag_by_name(char* name) { char flag_constant[255]; - int mapflag; + int64 mapflag; safesnprintf(flag_constant, sizeof(flag_constant), "mf_%s", name); diff --git a/src/map/mapreg.cpp b/src/map/mapreg.cpp index d42b0eeef6..bea0c517e1 100644 --- a/src/map/mapreg.cpp +++ b/src/map/mapreg.cpp @@ -34,7 +34,7 @@ struct reg_db regs; * @param uid: variable's unique identifier. * @return: variable's integer value */ -int mapreg_readreg(int64 uid) +int64 mapreg_readreg(int64 uid) { struct mapreg_save *m = (struct mapreg_save *)i64db_get(regs.vars, uid); return m ? m->u.i : 0; @@ -59,11 +59,11 @@ char* mapreg_readregstr(int64 uid) * @param val new value * @return: true value was successfully set */ -bool mapreg_setreg(int64 uid, int val) +bool mapreg_setreg(int64 uid, int64 val) { struct mapreg_save *m; int num = script_getvarid(uid); - unsigned int i = script_getvaridx(uid); + uint32 i = script_getvaridx(uid); const char* name = get_str(num); if (val != 0) { @@ -87,7 +87,7 @@ bool mapreg_setreg(int64 uid, int val) if (name[1] != '@' && !skip_insert) {// write new variable to database char esc_name[32 * 2 + 1]; Sql_EscapeStringLen(mmysql_handle, esc_name, name, strnlen(name, 32)); - if (SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg_table, esc_name, i, val)) + if (SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%" PRIu32 "','%" PRId64 "')", mapreg_table, esc_name, i, val)) Sql_ShowDebug(mmysql_handle); } i64db_put(regs.vars, uid, m); @@ -103,7 +103,7 @@ bool mapreg_setreg(int64 uid, int val) if (name[1] != '@') {// Remove from database because it is unused. char esc_name[32 * 2 + 1]; Sql_EscapeStringLen(mmysql_handle, esc_name, name, strnlen(name, 32)); - if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, esc_name, i)) + if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%" PRIu32 "'", mapreg_table, esc_name, i)) Sql_ShowDebug(mmysql_handle); } } @@ -122,7 +122,7 @@ bool mapreg_setregstr(int64 uid, const char* str) { struct mapreg_save *m; int num = script_getvarid(uid); - unsigned int i = script_getvaridx(uid); + uint32 i = script_getvaridx(uid); const char* name = get_str(num); if (str == NULL || *str == 0) { @@ -131,7 +131,7 @@ bool mapreg_setregstr(int64 uid, const char* str) if (name[1] != '@') { char esc_name[32 * 2 + 1]; Sql_EscapeStringLen(mmysql_handle, esc_name, name, strnlen(name, 32)); - if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg_table, esc_name, i)) + if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%" PRIu32 "'", mapreg_table, esc_name, i)) Sql_ShowDebug(mmysql_handle); } if ((m = static_cast(i64db_get(regs.vars, uid)))) { @@ -165,7 +165,7 @@ bool mapreg_setregstr(int64 uid, const char* str) char esc_str[255 * 2 + 1]; Sql_EscapeStringLen(mmysql_handle, esc_name, name, strnlen(name, 32)); Sql_EscapeStringLen(mmysql_handle, esc_str, str, strnlen(str, 255)); - if (SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg_table, esc_name, i, esc_str)) + if (SQL_ERROR == Sql_Query(mmysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%" PRIu32 "','%s')", mapreg_table, esc_name, i, esc_str)) Sql_ShowDebug(mmysql_handle); } i64db_put(regs.vars, uid, m); @@ -188,7 +188,7 @@ static void script_load_mapreg(void) */ SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle); char varname[32+1]; - int index; + uint32 index; char value[255+1]; uint32 length; @@ -203,21 +203,21 @@ static void script_load_mapreg(void) skip_insert = true; SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL); - SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 1, SQLDT_UINT32, &index, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL); while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) { int s = add_str(varname); - int i = index; + int64 uid = reference_uid(s, index); - if( i64db_exists(regs.vars, reference_uid(s, i)) ) { + if( i64db_exists(regs.vars, uid) ) { ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); continue; } if( varname[length-1] == '$' ) { - mapreg_setregstr(reference_uid(s, i), value); + mapreg_setregstr(uid, value); } else { - mapreg_setreg(reference_uid(s, i), atoi(value)); + mapreg_setreg(uid, strtoll(value,NULL,10)); } } @@ -238,19 +238,19 @@ static void script_save_mapreg(void) for (m = static_cast(dbi_first(iter)); dbi_exists(iter); m = static_cast(dbi_next(iter))) { if (m->save) { int num = script_getvarid(m->uid); - int i = script_getvaridx(m->uid); + uint32 i = script_getvaridx(m->uid); const char* name = get_str(num); if (!m->is_string) { char esc_name[32 * 2 + 1]; Sql_EscapeStringLen(mmysql_handle, esc_name, name, strnlen(name, 32)); - if (SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg_table, m->u.i, esc_name, i)) + if (SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%" PRId64 "' WHERE `varname`='%s' AND `index`='%" PRIu32 "' LIMIT 1", mapreg_table, m->u.i, esc_name, i)) Sql_ShowDebug(mmysql_handle); } else { char esc_str[2 * 255 + 1]; char esc_name[32 * 2 + 1]; Sql_EscapeStringLen(mmysql_handle, esc_name, name, strnlen(name, 32)); Sql_EscapeStringLen(mmysql_handle, esc_str, m->u.str, safestrnlen(m->u.str, 255)); - if (SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg_table, esc_str, esc_name, i)) + if (SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%" PRIu32 "' LIMIT 1", mapreg_table, esc_str, esc_name, i)) Sql_ShowDebug(mmysql_handle); } m->save = false; diff --git a/src/map/mapreg.hpp b/src/map/mapreg.hpp index c9f0041d8d..35f10528c8 100644 --- a/src/map/mapreg.hpp +++ b/src/map/mapreg.hpp @@ -10,7 +10,7 @@ struct mapreg_save { int64 uid; ///< Unique ID union { - int i; ///< Numeric value + int64 i; ///< Numeric value char *str; ///< String value } u; bool is_string; ///< true if it's a string, false if it's a number @@ -25,9 +25,9 @@ void mapreg_final(void); void mapreg_init(void); bool mapreg_config_read(const char* w1, const char* w2); -int mapreg_readreg(int64 uid); +int64 mapreg_readreg(int64 uid); char* mapreg_readregstr(int64 uid); -bool mapreg_setreg(int64 uid, int val); +bool mapreg_setreg(int64 uid, int64 val); bool mapreg_setregstr(int64 uid, const char* str); int mapreg_destroyreg(DBKey key, DBData *data, va_list ap); diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 9120b17d83..617e6780e3 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -4379,7 +4379,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asString(node, "Sprite", sprite)) return 0; - int constant; + int64 constant; if (script_get_constant(sprite.c_str(), &constant)) { if (npcdb_checkid(constant) == 0 && pcdb_checkid(constant) == 0) { @@ -4397,7 +4397,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { constant = sprite_mob->vd.class_; } - mob->vd.class_ = constant; + mob->vd.class_ = (unsigned short)constant; } else { this->invalidWarning(node["Sprite"], "Sprite is missing.\n"); return 0; @@ -4416,7 +4416,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { std::string sex_constant = "SEX_" + sex; - int constant; + int64 constant; if (!script_get_constant(sex_constant.c_str(), &constant)) { this->invalidWarning(node["Sex"], "Unknown sex constant %s.\n", sex.c_str()); @@ -4428,7 +4428,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { return 0; } - mob->vd.sex = constant; + mob->vd.sex = (char)constant; } if (this->nodeExists(node, "HairStyle")) { @@ -4620,7 +4620,7 @@ uint64 MobAvailDatabase::parseBodyNode(const YAML::Node &node) { for (const auto &optionNode : node["Options"]) { std::string option = optionNode.first.as(); std::string option_constant = "OPTION_" + option; - int constant; + int64 constant; if (!script_get_constant(option_constant.c_str(), &constant)) { this->invalidWarning(optionNode, "Unknown option constant %s, skipping.\n", option.c_str()); @@ -4665,9 +4665,14 @@ static bool mob_readdb_group(char* str[], int columns, int current){ if (ISDIGIT(str[0][0]) && ISDIGIT(str[0][1])) group = atoi(str[0]); - else if (!script_get_constant(str[0], &group)) { - ShowError("mob_readdb_group: Invalid random monster group '%s'\n", str[0]); - return false; + else { + int64 group_tmp; + + if (!script_get_constant(str[0], &group_tmp)) { + ShowError("mob_readdb_group: Invalid random monster group '%s'\n", str[0]); + return false; + } + group = static_cast(group_tmp); } mob_id = atoi(str[1]); @@ -5077,7 +5082,8 @@ static int mob_read_sqlskilldb(void) *------------------------------------------*/ static bool mob_readdb_race2(char* fields[], int columns, int current) { - int race, i; + int64 race; + int i; if( ISDIGIT(fields[0][0]) ) race = atoi(fields[0]); @@ -5087,7 +5093,7 @@ static bool mob_readdb_race2(char* fields[], int columns, int current) } if (!CHK_RACE2(race)) { - ShowWarning("mob_readdb_race2: Unknown race2 %d.\n", race); + ShowWarning("mob_readdb_race2: Unknown race2 %lld.\n", race); return false; } @@ -5096,7 +5102,7 @@ static bool mob_readdb_race2(char* fields[], int columns, int current) struct mob_db* db = mob_db(mob_id); if (db == NULL) { - ShowWarning("mob_readdb_race2: Unknown mob id %d for race2 %d.\n", mob_id, race); + ShowWarning("mob_readdb_race2: Unknown mob id %d for race2 %lld.\n", mob_id, race); continue; } db->race2 = (enum e_race2)race; @@ -5205,11 +5211,14 @@ static bool mob_readdb_drop(char* str[], int columns, int current) { drop[i].randomopt_group = 0; if (columns > 3) { + int64 randomopt_group_tmp = -1; int randomopt_group = -1; - if (!script_get_constant(trim(str[3]), &randomopt_group)) { + + if (!script_get_constant(trim(str[3]), &randomopt_group_tmp)) { ShowError("mob_readdb_drop: Invalid 'randopt_groupid' '%s' for monster '%hu'.\n", str[3], mobid); return false; } + randomopt_group = static_cast(randomopt_group_tmp); if (randomopt_group == RDMOPTG_None) return true; if (!itemdb_randomopt_group_exists(randomopt_group)) { diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 8bc7177fdb..839c6e5bcd 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -1704,7 +1704,7 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in clif_broadcast(&sd->bl, output, strlen(output) + 1, BC_BLUE,SELF); } - cost[0] = pc_readreg2(sd, nd->u.shop.pointshop_str); + cost[0] = static_cast(pc_readreg2(sd, nd->u.shop.pointshop_str)); break; } } @@ -1813,13 +1813,13 @@ static int npc_buylist_sub(struct map_session_data* sd, uint16 n, struct s_npc_b int i, key_nameid = 0, key_amount = 0; // discard old contents - script_cleararray_pc(sd, "@bought_nameid", (void*)0); - script_cleararray_pc(sd, "@bought_quantity", (void*)0); + script_cleararray_pc( sd, "@bought_nameid" ); + script_cleararray_pc( sd, "@bought_quantity" ); // save list of bought items for (i = 0; i < n; i++) { - script_setarray_pc(sd, "@bought_nameid", i, (void*)(intptr_t)item_list[i].nameid, &key_nameid); - script_setarray_pc(sd, "@bought_quantity", i, (void*)(intptr_t)item_list[i].qty, &key_amount); + script_setarray_pc( sd, "@bought_nameid", i, item_list[i].nameid, &key_nameid ); + script_setarray_pc( sd, "@bought_quantity", i, item_list[i].qty, &key_amount ); } // invoke event @@ -2000,28 +2000,28 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* int key_option_id[MAX_ITEM_RDM_OPT], key_option_val[MAX_ITEM_RDM_OPT], key_option_param[MAX_ITEM_RDM_OPT]; // discard old contents - script_cleararray_pc(sd, "@sold_nameid", (void*)0); - script_cleararray_pc(sd, "@sold_quantity", (void*)0); - script_cleararray_pc(sd, "@sold_refine", (void*)0); - script_cleararray_pc(sd, "@sold_attribute", (void*)0); - script_cleararray_pc(sd, "@sold_identify", (void*)0); + script_cleararray_pc( sd, "@sold_nameid" ); + script_cleararray_pc( sd, "@sold_quantity" ); + script_cleararray_pc( sd, "@sold_refine" ); + script_cleararray_pc( sd, "@sold_attribute" ); + script_cleararray_pc( sd, "@sold_identify" ); for( j = 0; j < MAX_SLOTS; j++ ) {// clear each of the card slot entries key_card[j] = 0; snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1); - script_cleararray_pc(sd, card_slot, (void*)0); + script_cleararray_pc( sd, card_slot ); } for (j = 0; j < MAX_ITEM_RDM_OPT; j++) { // Clear each of the item option entries key_option_id[j] = key_option_val[j] = key_option_param[j] = 0; snprintf(option_id, sizeof(option_id), "@sold_option_id%d", j + 1); - script_cleararray_pc(sd, option_id, (void *)0); + script_cleararray_pc( sd, option_id ); snprintf(option_val, sizeof(option_val), "@sold_option_val%d", j + 1); - script_cleararray_pc(sd, option_val, (void *)0); + script_cleararray_pc( sd, option_val ); snprintf(option_param, sizeof(option_param), "@sold_option_param%d", j + 1); - script_cleararray_pc(sd, option_param, (void *)0); + script_cleararray_pc( sd, option_param ); } // save list of to be sold items @@ -2029,28 +2029,28 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* { int idx = item_list[i * 2] - 2; - script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].nameid, &key_nameid); - script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount); + script_setarray_pc( sd, "@sold_nameid", i, sd->inventory.u.items_inventory[idx].nameid, &key_nameid ); + script_setarray_pc( sd, "@sold_quantity", i, item_list[i*2+1], &key_amount ); if( itemdb_isequip(sd->inventory.u.items_inventory[idx].nameid) ) {// process equipment based information into the arrays - script_setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].refine, &key_refine); - script_setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].attribute, &key_attribute); - script_setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].identify, &key_identify); + script_setarray_pc( sd, "@sold_refine", i, sd->inventory.u.items_inventory[idx].refine, &key_refine ); + script_setarray_pc( sd, "@sold_attribute", i, sd->inventory.u.items_inventory[idx].attribute, &key_attribute ); + script_setarray_pc( sd, "@sold_identify", i, sd->inventory.u.items_inventory[idx].identify, &key_identify ); for( j = 0; j < MAX_SLOTS; j++ ) {// store each of the cards from the equipment in the array snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1); - script_setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].card[j], &key_card[j]); + script_setarray_pc( sd, card_slot, i, sd->inventory.u.items_inventory[idx].card[j], &key_card[j] ); } for (j = 0; j < MAX_ITEM_RDM_OPT; j++) { // Store each of the item options in the array snprintf(option_id, sizeof(option_id), "@sold_option_id%d", j + 1); - script_setarray_pc(sd, option_id, i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].option[j].id, &key_option_id[j]); + script_setarray_pc( sd, option_id, i, sd->inventory.u.items_inventory[idx].option[j].id, &key_option_id[j] ); snprintf(option_val, sizeof(option_val), "@sold_option_val%d", j + 1); - script_setarray_pc(sd, option_val, i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].option[j].value, &key_option_val[j]); + script_setarray_pc( sd, option_val, i, sd->inventory.u.items_inventory[idx].option[j].value, &key_option_val[j] ); snprintf(option_param, sizeof(option_param), "@sold_option_param%d", j + 1); - script_setarray_pc(sd, option_param, i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].option[j].param, &key_option_param[j]); + script_setarray_pc( sd, option_param, i, sd->inventory.u.items_inventory[idx].option[j].param, &key_option_param[j] ); } } } @@ -2544,11 +2544,14 @@ int npc_parseview(const char* w4, const char* start, const char* buffer, const c // Check if view id is not an ID (only numbers). if (pid != nullptr && *pid != '\0') { + int64 val_tmp; + // Check if constant exists and get its value. - if(!script_get_constant(viewid, &val)) { + if(!script_get_constant(viewid, &val_tmp)) { ShowWarning("npc_parseview: Invalid NPC constant '%s' specified in file '%s', line'%d'. Defaulting to INVISIBLE. \n", viewid, filepath, strline(buffer,start-buffer)); val = JT_INVISIBLE; - } + } else + val = static_cast(val_tmp); } return val; @@ -3795,7 +3798,7 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c } st = script_alloc_state(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id); - setd_sub(st, NULL, ".@atcmd_command$", 0, (void *)command, NULL); + setd_sub_str( st, NULL, ".@atcmd_command$", 0, command, NULL ); // split atcmd parameters based on spaces @@ -3809,7 +3812,7 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c temp[k] = '\0'; k = 0; if( temp[0] != '\0' ) { - setd_sub( st, NULL, ".@atcmd_parameters$", j++, (void *)temp, NULL ); + setd_sub_str( st, NULL, ".@atcmd_parameters$", j++, temp, NULL ); } } else { temp[k] = message[i]; @@ -3817,7 +3820,7 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c } } - setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)__64BPRTSIZE(j), NULL); + setd_sub_num( st, NULL, ".@atcmd_numparameters", 0, j, NULL ); aFree(temp); run_script_main(st); @@ -4185,13 +4188,15 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con if (ISDIGIT(caster_constant[0])) args.skill_damage.caster = atoi(caster_constant); else { + int64 val_tmp; int val; - if (!script_get_constant(caster_constant, &val)) { + if (!script_get_constant(caster_constant, &val_tmp)) { ShowError( "npc_parse_mapflag: Unknown constant '%s'. Skipping (file '%s', line '%d').\n", caster_constant, filepath, strline(buffer, start - buffer) ); break; } + val = static_cast(val_tmp); args.skill_damage.caster = val; } diff --git a/src/map/npc_chat.cpp b/src/map/npc_chat.cpp index 2ee049c18d..118c50dfd4 100644 --- a/src/map/npc_chat.cpp +++ b/src/map/npc_chat.cpp @@ -76,7 +76,7 @@ struct pcrematch_set { struct pcrematch_set* prev; struct pcrematch_set* next; struct pcrematch_entry* head; - int setid; + int64 setid; }; /* @@ -110,7 +110,7 @@ void finalize_pcrematch_entry(struct pcrematch_entry* e) /** * Lookup (and possibly create) a new set of patterns by the set id */ -static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) +static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int64 setid) { struct pcrematch_set *pcreset; struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; @@ -151,7 +151,7 @@ static struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) * * if the setid does not exist, this will silently return */ -static void activate_pcreset(struct npc_data* nd, int setid) +static void activate_pcreset(struct npc_data* nd, int64 setid) { struct pcrematch_set *pcreset; struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; @@ -184,7 +184,7 @@ static void activate_pcreset(struct npc_data* nd, int setid) * * if the setid does not exist, this will silently return */ -static void deactivate_pcreset(struct npc_data* nd, int setid) +static void deactivate_pcreset(struct npc_data* nd, int64 setid) { struct pcrematch_set *pcreset; struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; @@ -220,7 +220,7 @@ static void deactivate_pcreset(struct npc_data* nd, int setid) /** * delete a set of patterns. */ -static void delete_pcreset(struct npc_data* nd, int setid) +static void delete_pcreset(struct npc_data* nd, int64 setid) { int active = 1; struct pcrematch_set *pcreset; @@ -300,7 +300,7 @@ static struct pcrematch_entry* create_pcrematch_entry(struct pcrematch_set* set) /** * define/compile a new pattern */ -void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, const char* label) +void npc_chat_def_pattern(struct npc_data* nd, int64 setid, const char* pattern, const char* label) { const char *err; int erroff; @@ -375,7 +375,7 @@ int npc_chat_sub(struct block_list* bl, va_list ap) char var[255], val[255]; snprintf(var, sizeof(var), "$@p%i$", i); pcre_copy_substring(msg, offsets, r, i, val, sizeof(val)); - set_var(sd, var, val); + set_var_str( sd, var, val ); } // find the target label.. this sucks.. @@ -400,7 +400,7 @@ int npc_chat_sub(struct block_list* bl, va_list ap) int buildin_defpattern(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int64 setid = conv_num64(st,& (st->stack->stack_data[st->start+2])); const char* pattern = conv_str(st,& (st->stack->stack_data[st->start+3])); const char* label = conv_str(st,& (st->stack->stack_data[st->start+4])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); @@ -412,7 +412,7 @@ int buildin_defpattern(struct script_state* st) int buildin_activatepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int64 setid = conv_num64(st,& (st->stack->stack_data[st->start+2])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); activate_pcreset(nd, setid); @@ -422,7 +422,7 @@ int buildin_activatepset(struct script_state* st) int buildin_deactivatepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int64 setid = conv_num64(st,& (st->stack->stack_data[st->start+2])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); deactivate_pcreset(nd, setid); @@ -432,7 +432,7 @@ int buildin_deactivatepset(struct script_state* st) int buildin_deletepset(struct script_state* st) { - int setid = conv_num(st,& (st->stack->stack_data[st->start+2])); + int64 setid = conv_num64(st,& (st->stack->stack_data[st->start+2])); struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); delete_pcreset(nd, setid); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index a4abc22c5b..5f1aaf9cb0 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -1603,34 +1603,34 @@ void pc_reg_received(struct map_session_data *sd) sd->vars_ok = true; - sd->change_level_2nd = pc_readglobalreg(sd, add_str(JOBCHANGE2ND_VAR)); - sd->change_level_3rd = pc_readglobalreg(sd, add_str(JOBCHANGE3RD_VAR)); - sd->die_counter = pc_readglobalreg(sd, add_str(PCDIECOUNTER_VAR)); + sd->change_level_2nd = static_cast(pc_readglobalreg(sd, add_str(JOBCHANGE2ND_VAR))); + sd->change_level_3rd = static_cast(pc_readglobalreg(sd, add_str(JOBCHANGE3RD_VAR))); + sd->die_counter = static_cast(pc_readglobalreg(sd, add_str(PCDIECOUNTER_VAR))); - sd->langtype = pc_readaccountreg(sd, add_str(LANGTYPE_VAR)); + sd->langtype = static_cast(pc_readaccountreg(sd, add_str(LANGTYPE_VAR))); if (msg_checklangtype(sd->langtype,true) < 0) sd->langtype = 0; //invalid langtype reset to default // Cash shop - sd->cashPoints = pc_readaccountreg(sd, add_str(CASHPOINT_VAR)); - sd->kafraPoints = pc_readaccountreg(sd, add_str(KAFRAPOINT_VAR)); + sd->cashPoints = static_cast(pc_readaccountreg(sd, add_str(CASHPOINT_VAR))); + sd->kafraPoints = static_cast(pc_readaccountreg(sd, add_str(KAFRAPOINT_VAR))); // Cooking Exp - sd->cook_mastery = pc_readglobalreg(sd, add_str(COOKMASTERY_VAR)); + sd->cook_mastery = static_cast(pc_readglobalreg(sd, add_str(COOKMASTERY_VAR))); if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) { // Better check for class rather than skill to prevent "skill resets" from unsetting this - sd->mission_mobid = pc_readglobalreg(sd, add_str(TKMISSIONID_VAR)); - sd->mission_count = pc_readglobalreg(sd, add_str(TKMISSIONCOUNT_VAR)); + sd->mission_mobid = static_cast(pc_readglobalreg(sd, add_str(TKMISSIONID_VAR))); + sd->mission_count = static_cast(pc_readglobalreg(sd, add_str(TKMISSIONCOUNT_VAR))); } if (battle_config.feature_banking) - sd->bank_vault = pc_readreg2(sd, BANK_VAULT_VAR); + sd->bank_vault = static_cast(pc_readreg2(sd, BANK_VAULT_VAR)); if (battle_config.feature_roulette) { - sd->roulette_point.bronze = pc_readreg2(sd, ROULETTE_BRONZE_VAR); - sd->roulette_point.silver = pc_readreg2(sd, ROULETTE_SILVER_VAR); - sd->roulette_point.gold = pc_readreg2(sd, ROULETTE_GOLD_VAR); + sd->roulette_point.bronze = static_cast(pc_readreg2(sd, ROULETTE_BRONZE_VAR)); + sd->roulette_point.silver = static_cast(pc_readreg2(sd, ROULETTE_SILVER_VAR)); + sd->roulette_point.gold = static_cast(pc_readreg2(sd, ROULETTE_GOLD_VAR)); } sd->roulette.prizeIdx = -1; @@ -1638,33 +1638,33 @@ void pc_reg_received(struct map_session_data *sd) for(i=0;i(pc_readglobalreg(sd, add_str(sg_info[i].feel_var)))) != 0) { sd->feel_map[i].index = j; sd->feel_map[i].m = map_mapindex2mapid(j); } else { sd->feel_map[i].index = 0; sd->feel_map[i].m = -1; } - sd->hate_mob[i] = pc_readglobalreg(sd, add_str(sg_info[i].hate_var))-1; + sd->hate_mob[i] = static_cast(pc_readglobalreg(sd, add_str(sg_info[i].hate_var)))-1; } if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) { - unsigned short skid = pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM)); + unsigned short skid = static_cast(pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM))); sd->cloneskill_idx = skill_get_index(skid); if (sd->cloneskill_idx > 0) { sd->status.skill[sd->cloneskill_idx].id = skid; - sd->status.skill[sd->cloneskill_idx].lv = pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM_LV)); + sd->status.skill[sd->cloneskill_idx].lv = static_cast(pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM_LV))); if (sd->status.skill[sd->cloneskill_idx].lv > i) sd->status.skill[sd->cloneskill_idx].lv = i; sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PLAGIARIZED; } } if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) { - unsigned short skid = pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE)); + unsigned short skid = static_cast(pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE))); sd->reproduceskill_idx = skill_get_index(skid); if (sd->reproduceskill_idx > 0) { sd->status.skill[sd->reproduceskill_idx].id = skid; - sd->status.skill[sd->reproduceskill_idx].lv = pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE_LV)); + sd->status.skill[sd->reproduceskill_idx].lv = static_cast(pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE_LV))); if (i < sd->status.skill[sd->reproduceskill_idx].lv) sd->status.skill[sd->reproduceskill_idx].lv = i; sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PLAGIARIZED; @@ -8365,9 +8365,9 @@ bool pc_revive_item(struct map_session_data *sd) { /*========================================== * script reading pc status registry *------------------------------------------*/ -int pc_readparam(struct map_session_data* sd,int type) +int64 pc_readparam(struct map_session_data* sd,int64 type) { - int val = 0; + int64 val = 0; nullpo_ret(sd); @@ -8527,7 +8527,7 @@ int pc_readparam(struct map_session_data* sd,int type) val = sd->castrate; break; #endif default: - ShowError("pc_readparam: Attempt to read unknown parameter '%d'.\n", type); + ShowError("pc_readparam: Attempt to read unknown parameter '%lld'.\n", type); return -1; } @@ -8537,22 +8537,24 @@ int pc_readparam(struct map_session_data* sd,int type) /*========================================== * script set pc status registry *------------------------------------------*/ -bool pc_setparam(struct map_session_data *sd,int type,int val) +bool pc_setparam(struct map_session_data *sd,int64 type,int64 val_tmp) { nullpo_retr(false,sd); + int val = static_cast(val_tmp); + switch(type){ case SP_BASELEVEL: - if ((unsigned int)val > pc_maxbaselv(sd)) //Capping to max + if (val > pc_maxbaselv(sd)) //Capping to max val = pc_maxbaselv(sd); - if ((unsigned int)val > sd->status.base_level) { + if (val > sd->status.base_level) { int i = 0; int stat=0; - for (i = 0; i < (int)((unsigned int)val - sd->status.base_level); i++) + for (i = 0; i < (int)(val - sd->status.base_level); i++) stat += pc_gets_status_point(sd->status.base_level + i); sd->status.status_point += stat; } - sd->status.base_level = (unsigned int)val; + sd->status.base_level = val; sd->status.base_exp = 0; // clif_updatestatus(sd, SP_BASELEVEL); // Gets updated at the bottom clif_updatestatus(sd, SP_NEXTBASEEXP); @@ -8563,12 +8565,12 @@ bool pc_setparam(struct map_session_data *sd,int type,int val) party_send_levelup(sd); break; case SP_JOBLEVEL: - if ((unsigned int)val >= sd->status.job_level) { - if ((unsigned int)val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd); + if (val >= sd->status.job_level) { + if (val > pc_maxjoblv(sd)) val = pc_maxjoblv(sd); sd->status.skill_point += val - sd->status.job_level; clif_updatestatus(sd, SP_SKILLPOINT); } - sd->status.job_level = (unsigned int)val; + sd->status.job_level = val; sd->status.job_exp = 0; // clif_updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom clif_updatestatus(sd, SP_NEXTJOBEXP); @@ -8590,7 +8592,7 @@ bool pc_setparam(struct map_session_data *sd,int type,int val) case SP_BASEEXP: { val = cap_value(val, 0, INT_MAX); - if ((unsigned int)val < sd->status.base_exp) // Lost + if (val < sd->status.base_exp) // Lost pc_lostexp(sd, sd->status.base_exp - val, 0); else // Gained pc_gainexp(sd, NULL, val - sd->status.base_exp, 0, 2); @@ -8599,7 +8601,7 @@ bool pc_setparam(struct map_session_data *sd,int type,int val) case SP_JOBEXP: { val = cap_value(val, 0, INT_MAX); - if ((unsigned int)val < sd->status.job_exp) // Lost + if (val < sd->status.job_exp) // Lost pc_lostexp(sd, 0, sd->status.job_exp - val); else // Gained pc_gainexp(sd, NULL, 0, val - sd->status.job_exp, 2); @@ -8750,10 +8752,10 @@ bool pc_setparam(struct map_session_data *sd,int type,int val) pc_setglobalreg(sd, add_str(COOKMASTERY_VAR), sd->cook_mastery); return true; default: - ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type); + ShowError("pc_setparam: Attempted to set unknown parameter '%lld'.\n", type); return false; } - clif_updatestatus(sd,type); + clif_updatestatus(sd,static_cast(type)); return true; } @@ -8972,7 +8974,7 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper) sd->status.skill[sd->cloneskill_idx].id = 0; sd->status.skill[sd->cloneskill_idx].lv = 0; sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT; - clif_deleteskill(sd,pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM))); + clif_deleteskill(sd, static_cast(pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM)))); } sd->cloneskill_idx = 0; pc_setglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM), 0); @@ -8984,7 +8986,7 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper) sd->status.skill[sd->reproduceskill_idx].id = 0; sd->status.skill[sd->reproduceskill_idx].lv = 0; sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT; - clif_deleteskill(sd,pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE))); + clif_deleteskill(sd, static_cast(pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE)))); } sd->reproduceskill_idx = 0; pc_setglobalreg(sd, add_str(SKILL_VAR_REPRODUCE), 0); @@ -9469,22 +9471,22 @@ bool pc_can_attack( struct map_session_data *sd, int target_id ) { /*========================================== * Read '@type' variables (temporary numeric char reg) *------------------------------------------*/ -int pc_readreg(struct map_session_data* sd, int64 reg) +int64 pc_readreg(struct map_session_data* sd, int64 reg) { - return i64db_iget(sd->regs.vars, reg); + return i64db_i64get(sd->regs.vars, reg); } /*========================================== * Set '@type' variables (temporary numeric char reg) *------------------------------------------*/ -bool pc_setreg(struct map_session_data* sd, int64 reg, int val) +bool pc_setreg(struct map_session_data* sd, int64 reg, int64 val) { - unsigned int index = script_getvaridx(reg); + uint32 index = script_getvaridx(reg); nullpo_retr(false, sd); if( val ) { - i64db_iput(sd->regs.vars, reg, val); + i64db_i64put(sd->regs.vars, reg, val); if( index ) script_array_update(&sd->regs, reg, false); } else { @@ -9554,7 +9556,7 @@ bool pc_setregstr(struct map_session_data* sd, int64 reg, const char* str) * - '#type' (permanent numeric account reg) * - '##type' (permanent numeric account reg2) **/ -int pc_readregistry(struct map_session_data *sd, int64 reg) +int64 pc_readregistry(struct map_session_data *sd, int64 reg) { struct script_reg_num *p = NULL; @@ -9600,12 +9602,12 @@ char* pc_readregistry_str(struct map_session_data *sd, int64 reg) * - '#type' (permanent numeric account reg) * - '##type' (permanent numeric account reg2) **/ -int pc_setregistry(struct map_session_data *sd, int64 reg, int val) +int pc_setregistry(struct map_session_data *sd, int64 reg, int64 val) { struct script_reg_num *p = NULL; const char *regname = get_str(script_getvarid(reg)); - unsigned int index = script_getvaridx(reg); - + uint32 index = script_getvaridx(reg); + if ( !reg_load && !sd->vars_ok ) { ShowError("pc_setregistry : refusing to set %s until vars are received.\n", regname); return 0; @@ -9721,7 +9723,7 @@ int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val) * @param value * @return True if success, false if failed. **/ -bool pc_setreg2(struct map_session_data *sd, const char *reg, int val) { +bool pc_setreg2(struct map_session_data *sd, const char *reg, int64 val) { char prefix = reg[0]; nullpo_retr(false, sd); @@ -9756,7 +9758,7 @@ bool pc_setreg2(struct map_session_data *sd, const char *reg, int val) { * @param reg Variable name * @return Variable value or 0 if failed. **/ -int pc_readreg2(struct map_session_data *sd, const char *reg) { +int64 pc_readreg2(struct map_session_data *sd, const char *reg) { char prefix = reg[0]; nullpo_ret(sd); @@ -11854,10 +11856,12 @@ static bool pc_readdb_job_basehpsp(char* fields[], int columns, int current) */ static bool pc_readdb_job_param(char* fields[], int columns, int current) { + int64 class_tmp; int idx, class_; uint16 str, agi, vit, int_, dex, luk; - script_get_constant(trim(fields[0]),&class_); + script_get_constant(trim(fields[0]),&class_tmp); + class_ = static_cast(class_tmp); if ((idx = pc_class2idx(class_)) < 0) { ShowError("pc_readdb_job_param: Invalid job '%s'. Skipping!",fields[0]); @@ -11885,14 +11889,16 @@ static bool pc_readdb_job_param(char* fields[], int columns, int current) **/ static bool pc_readdb_job_noenter_map(char *str[], int columns, int current) { int idx, class_ = -1; + int64 class_tmp; if (ISDIGIT(str[0][0])) { class_ = atoi(str[0]); } else { - if (!script_get_constant(str[0], &class_)) { + if (!script_get_constant(str[0], &class_tmp)) { ShowError("pc_readdb_job_noenter_map: Invalid job %s specified.\n", str[0]); return false; } + class_ = static_cast(class_tmp); } if (!pcdb_checkid(class_) || (idx = pc_class2idx(class_)) < 0) { @@ -13106,7 +13112,7 @@ int32 pc_attendance_counter( struct map_session_data* sd ){ } // Get the counter for the current period - int counter = pc_readreg2( sd, ATTENDANCE_COUNT_VAR ); + int counter = static_cast(pc_readreg2( sd, ATTENDANCE_COUNT_VAR )); // Check if we have a remaining counter from a previous period if( counter > 0 && pc_readreg2( sd, ATTENDANCE_DATE_VAR ) < period->start ){ @@ -13135,7 +13141,7 @@ void pc_attendance_claim_reward( struct map_session_data* sd ){ return; } - int32 attendance_counter = pc_readreg2( sd, ATTENDANCE_COUNT_VAR ); + int32 attendance_counter = static_cast(pc_readreg2( sd, ATTENDANCE_COUNT_VAR )); attendance_counter += 1; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 2932ae9269..69929e49f4 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -1181,14 +1181,14 @@ void pc_changelook(struct map_session_data *,int,int); void pc_equiplookall(struct map_session_data *sd); void pc_set_costume_view(struct map_session_data *sd); -int pc_readparam(struct map_session_data *sd, int type); -bool pc_setparam(struct map_session_data *sd, int type, int val); -int pc_readreg(struct map_session_data *sd, int64 reg); -bool pc_setreg(struct map_session_data *sd, int64 reg, int val); +int64 pc_readparam(struct map_session_data *sd, int64 type); +bool pc_setparam(struct map_session_data *sd, int64 type, int64 val); +int64 pc_readreg(struct map_session_data *sd, int64 reg); +bool pc_setreg(struct map_session_data *sd, int64 reg, int64 val); char *pc_readregstr(struct map_session_data *sd, int64 reg); bool pc_setregstr(struct map_session_data *sd, int64 reg, const char *str); -int pc_readregistry(struct map_session_data *sd, int64 reg); -int pc_setregistry(struct map_session_data *sd, int64 reg, int val); +int64 pc_readregistry(struct map_session_data *sd, int64 reg); +int pc_setregistry(struct map_session_data *sd, int64 reg, int64 val); char *pc_readregistry_str(struct map_session_data *sd, int64 reg); int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val); @@ -1205,8 +1205,8 @@ int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val); #define pc_readaccountreg2str(sd,reg) pc_readregistry_str(sd,reg) #define pc_setaccountreg2str(sd,reg,val) pc_setregistry_str(sd,reg,val) -bool pc_setreg2(struct map_session_data *sd, const char *reg, int val); -int pc_readreg2(struct map_session_data *sd, const char *reg); +bool pc_setreg2(struct map_session_data *sd, const char *reg, int64 val); +int64 pc_readreg2(struct map_session_data *sd, const char *reg); bool pc_addeventtimer(struct map_session_data *sd,int tick,const char *name); bool pc_deleventtimer(struct map_session_data *sd,const char *name); diff --git a/src/map/script.cpp b/src/map/script.cpp index 6fb9decdd8..200c7d0b29 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -28,6 +28,7 @@ #include "../common/socket.hpp" #include "../common/strlib.hpp" #include "../common/timer.hpp" +#include "../common/utilities.hpp" #include "../common/utils.hpp" #include "achievement.hpp" @@ -61,6 +62,11 @@ #include "quest.hpp" #include "storage.hpp" +using namespace rathena; + +const int64 SCRIPT_INT_MIN = INT64_MIN; +const int64 SCRIPT_INT_MAX = INT64_MAX; + struct eri *array_ers; DBMap *st_db; unsigned int active_scripts; @@ -208,7 +214,7 @@ static struct str_data_struct { int backpatch; int label; int (*func)(struct script_state *st); - int val; + int64 val; int next; const char *name; bool deprecated; @@ -361,7 +367,7 @@ unsigned int generic_ui_array_size = 0; c_op get_com(unsigned char *script,int *pos); -int get_num(unsigned char *script,int *pos); +int64 get_num(unsigned char *script,int *pos); typedef struct script_function { int (*func)(struct script_state *st); @@ -531,9 +537,9 @@ static void script_reportdata(struct script_data* data) const char* name = reference_getname(data); ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data)); } else if( reference_toconstant(data) ) {// constant - ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data)); + ShowDebug("Data: constant name='%s' value=%" PRId64 "\n", reference_getname(data), reference_getconstant(data)); } else if( reference_toparam(data) ) {// param - ShowDebug("Data: param name='%s' type=%d\n", reference_getname(data), reference_getparamtype(data)); + ShowDebug("Data: param name='%s' type=%" PRId64 "\n", reference_getname(data), reference_getparamtype(data)); } else {// ??? ShowDebug("Data: reference name='%s' type=%s\n", reference_getname(data), script_op2name(data->type)); ShowDebug("Please report this!!! - script->str_data.type=%s\n", script_op2name(str_data[reference_getid(data)].type)); @@ -746,14 +752,14 @@ int add_str(const char* p) /// Appends 1 byte to the script buffer. -static void add_scriptb(int a) +static void add_scriptb(uint8 a) { if( script_pos+1 >= script_size ) { script_size += SCRIPT_BLOCK_SIZE; RECREATE(script_buf,unsigned char,script_size); } - script_buf[script_pos++] = (uint8)(a); + script_buf[script_pos++] = a; } /// Appends a c_op value to the script buffer. @@ -774,15 +780,14 @@ static void add_scriptc(int a) /// Appends an integer value to the script buffer. /// The value is variable-length encoded into 8-bit blocks. /// The encoding scheme is ( 11?????? )* 10??????, LSB first. -/// All blocks but the last hold 7 bits of data, topmost bit is always 1 (carries). -static void add_scripti(int a) -{ - while( a >= 0x40 ) - { - add_scriptb((a&0x3f)|0xc0); - a = (a - 0x40) >> 6; +/// All blocks hold 6 bits of data. +static void add_scripti(int64 a){ + while( a > 0x3f ){ + add_scriptb((a & (int64)0x3f)|(int64)0xc0); + a >>= 6; } - add_scriptb(a|0x80); + + add_scriptb(((a & (int64)0x3f)|(int64)0x80)); } /// Appends a str_data object (label/function/variable/integer) to the script buffer. @@ -812,7 +817,7 @@ static void add_scriptl(int l) add_scriptb(backpatch>>16); break; case C_INT: - add_scripti(abs(str_data[l].val)); + add_scripti(std::abs(str_data[l].val)); if( str_data[l].val < 0 ) //Notice that this is negative, from jA (Rayce) add_scriptc(C_NEG); break; @@ -1281,7 +1286,7 @@ bool is_number(const char *p) { *------------------------------------------*/ const char* parse_simpleexpr(const char *p) { - long long i; + int64 i; p=skip_space(p); if(*p==';' || *p==',') @@ -1305,16 +1310,24 @@ const char* parse_simpleexpr(const char *p) ++p; } else if(is_number(p)) { char *np; + bool error; + + // Skip leading zeroes while(*p == '0' && ISDIGIT(p[1])) p++; + + errno = 0; i=strtoll(p,&np,0); - if( i < INT_MIN ) { - i = INT_MIN; - disp_warning_message("parse_simpleexpr: underflow detected, capping value to INT_MIN",p); - } else if( i > INT_MAX ) { - i = INT_MAX; - disp_warning_message("parse_simpleexpr: overflow detected, capping value to INT_MAX",p); + error = (errno == ERANGE); + + if( i < SCRIPT_INT_MIN || ( error && i == INT64_MIN ) ){ + i = SCRIPT_INT_MIN; + disp_warning_message( "parse_simpleexpr: underflow detected, capping value to SCRIPT_INT_MIN", p ); + }else if( i > SCRIPT_INT_MAX || ( error && i == INT64_MAX ) ){ + i = SCRIPT_INT_MAX; + disp_warning_message( "parse_simpleexpr: overflow detected, capping value to SCRIPT_INT_MAX", p ); } - add_scripti((int)i); + + add_scripti(i); p=np; } else if(*p=='"'){ add_scriptc(C_STR); @@ -1637,7 +1650,8 @@ const char* parse_syntax(const char* p) return p+1; } else { char label[256]; - int l,v; + int l; + int64 v; char *np; if(syntax.curly[pos].count != 1) { //Jump for FALLTHRU @@ -1669,7 +1683,7 @@ const char* parse_syntax(const char* p) //Check for constants p2 = skip_word(p); v = (int)(size_t) (p2-p); // length of word at p2 - memcpy(label,p,v); + memcpy(label,p,static_cast(v)); label[v]='\0'; if( !script_get_constant(label, &v) ) disp_error_message("parse_syntax: 'case' label is not an integer",p); @@ -1678,7 +1692,7 @@ const char* parse_syntax(const char* p) p = skip_space(p); if(*p != ':') disp_error_message("parse_syntax: expect ':'",p); - sprintf(label,"if(%d != $@__SW%x_VAL) goto __SW%x_%x;", + sprintf(label,"if(%lld != $@__SW%x_VAL) goto __SW%x_%x;", v,syntax.curly[pos].index,syntax.curly[pos].index,syntax.curly[pos].count+1); syntax.curly[syntax.curly_count++].type = TYPE_NULL; // Bad I do not parse twice @@ -2277,7 +2291,7 @@ const char* script_get_constant_str( const char* prefix, int64 value ){ } /// Retrieves the value of a constant parameter. -bool script_get_parameter(const char* name, int* value) +bool script_get_parameter(const char* name, int64* value) { int n = search_str(name); @@ -2291,7 +2305,7 @@ bool script_get_parameter(const char* name, int* value) } /// Retrieves the value of a constant. -bool script_get_constant(const char* name, int* value) +bool script_get_constant(const char* name, int64* value) { int n = search_str(name); @@ -2314,7 +2328,7 @@ bool script_get_constant(const char* name, int* value) } /// Creates new constant or parameter with given value. -void script_set_constant_(const char* name, int value, const char* constant_name, bool isparameter, bool deprecated) +void script_set_constant_(const char* name, int64 value, const char* constant_name, bool isparameter, bool deprecated) { int n = add_str(name); @@ -2327,7 +2341,7 @@ void script_set_constant_(const char* name, int value, const char* constant_name } else if( str_data[n].type == C_PARAM || str_data[n].type == C_INT ) {// existing parameter or constant - ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", ( str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, str_data[n].val, value); + ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%" PRId64 ", new value=%" PRId64 ").\n", ( str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, str_data[n].val, value); } else {// existing name @@ -2799,7 +2813,7 @@ struct script_data *get_val_(struct script_state* st, struct script_data* data, st->stack->scope.vars : // instance/scope variable st->script->local.vars; // npc variable if( n ) - data->u.num = (int)i64db_iget(n,reference_getuid(data)); + data->u.num = i64db_i64get(n,reference_getuid(data)); else data->u.num = 0; } @@ -2815,7 +2829,7 @@ struct script_data *get_val_(struct script_state* st, struct script_data* data, n = instance_data[instance_id].regs.vars; } if (n) - data->u.num = (int)i64db_iget(n,reference_getuid(data)); + data->u.num = i64db_i64get(n,reference_getuid(data)); else { ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to 0\n", name); data->u.num = 0; @@ -2840,20 +2854,44 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) struct script_data* push_val2(struct script_stack* stack, enum c_op type, int64 val, struct reg_db* ref); -/// Retrieves the value of a reference identified by uid (variable, constant, param) -/// The value is left in the top of the stack and needs to be removed manually. -/// @param st[in]: script state. -/// @param uid[in]: reference identifier. -/// @param ref[in]: the container to look up the reference into. -/// @return: the retrieved value of the reference. -void* get_val2(struct script_state* st, int64 uid, struct reg_db *ref) -{ - struct script_data* data; - push_val2(st->stack, C_NAME, uid, ref); - data = script_getdatatop(st, -1); - get_val(st, data); - //! TODO: Support data->u.num as int64 instead cast it to int? (in get_val, it was casted to int). - return (data->type == C_INT ? (void*)__64BPRTSIZE((int)data->u.num) : (void*)__64BPRTSIZE(data->u.str)); +const char* get_val2_str( struct script_state* st, int64 uid, struct reg_db* ref ){ + push_val2( st->stack, C_NAME, uid, ref ); + + struct script_data* data = script_getdatatop( st, -1 ); + + get_val( st, data ); + + const char* value = ""; + + if( data->type == C_INT ){ + ShowError( "get_val2_num: Invalid call. Variable %s is a numeric type.\n", reference_getname( data ) ); + }else{ + value = data->u.str; + } + + script_removetop( st, -1, 0 ); + + return value; +} + +int64 get_val2_num( struct script_state* st, int64 uid, struct reg_db* ref ){ + push_val2( st->stack, C_NAME, uid, ref ); + + struct script_data* data = script_getdatatop( st, -1 ); + + get_val( st, data ); + + int64 value = 0; + + if( data->type == C_INT ){ + value = data->u.num; + }else{ + ShowError( "get_val2_num: Invalid call. Variable %s is not a numeric type.\n", reference_getname( data ) ); + } + + script_removetop( st, -1, 0 ); + + return value; } /** @@ -2872,15 +2910,13 @@ void script_array_ensure_zero(struct script_state *st, struct map_session_data * insert = true; } else { if( is_string_variable(name) ) { - char* str = (char*)get_val2(st, uid, ref); + const char* str = get_val2_str( st, uid, ref ); if( str && *str ) insert = true; - script_removetop(st, -1, 0); } else { - int32 num = (int32)__64BPRTSIZE(get_val2(st, uid, ref)); + int64 num = get_val2_num( st, uid, ref ); if( num ) insert = true; - script_removetop(st, -1, 0); } } @@ -3111,157 +3147,200 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) * * TODO: return values are screwed up, have been for some time (reaad: years), e.g. some functions return 1 failure and success. *------------------------------------------*/ -int set_reg(struct script_state* st, struct map_session_data* sd, int64 num, const char* name, const void* value, struct reg_db *ref) -{ +bool set_reg_str( struct script_state* st, struct map_session_data* sd, int64 num, const char* name, const char* value, struct reg_db *ref ){ char prefix = name[0]; size_t vlen = 0; - if ( !script_check_RegistryVariableLength(0,name,&vlen) ) - { - ShowError("set_reg: Variable name length is too long (aid: %d, cid: %d): '%s' sz=%" PRIuPTR "\n", sd?sd->status.account_id:-1, sd?sd->status.char_id:-1, name, vlen); - return 0; + + if( !script_check_RegistryVariableLength( 0, name, &vlen ) ){ + ShowError( "set_reg: Variable name length is too long (aid: %d, cid: %d): '%s' sz=%" PRIuPTR "\n", sd ? sd->status.account_id : -1, sd ? sd->status.char_id : -1, name, vlen ); + return false; } - if( is_string_variable(name) ) {// string variable - const char *str = (const char*)value; + if( !is_string_variable( name ) ){ + // integer variable + return false; + } - switch (prefix) { - case '@': - pc_setregstr(sd, num, str); - return 1; - case '$': - return mapreg_setregstr(num, str); - case '#': - return (name[1] == '#') ? - pc_setaccountreg2str(sd, num, str) : - pc_setaccountregstr(sd, num, str); - case '.': - { - struct reg_db *n = (ref) ? ref : (name[1] == '@') ? &st->stack->scope : &st->script->local; - if( n ) { - if (str[0]) { - i64db_put(n->vars, num, aStrdup(str)); - if( script_getvaridx(num) ) - script_array_update(n, num, false); - } else { - i64db_remove(n->vars, num); - if( script_getvaridx(num) ) - script_array_update(n, num, true); + switch( prefix ){ + case '@': + pc_setregstr( sd, num, value ); + return true; + case '$': + return mapreg_setregstr( num, value ); + case '#': + return ( name[1] == '#' ) ? pc_setaccountreg2str( sd, num, value ) : pc_setaccountregstr( sd, num, value ); + case '.': { + struct reg_db *n = ( ref ) ? ref : ( name[1] == '@' ) ? &st->stack->scope : &st->script->local; + + if( n ){ + if( value[0] ){ + i64db_put( n->vars, num, aStrdup( value ) ); + + if( script_getvaridx( num ) ){ + script_array_update( n, num, false ); + } + }else{ + i64db_remove( n->vars, num ); + + if( script_getvaridx( num ) ){ + script_array_update( n, num, true ); } } } - return 1; - case '\'': - { - struct reg_db *src = nullptr; - if (ref) - src = ref; - else { - unsigned short instance_id = script_instancegetid(st); - if (instance_id != 0) - src = &instance_data[instance_id].regs; - } - if (src) { - bool empty; - if (str[0]) { - i64db_put(src->vars, num, aStrdup(str)); - empty = false; - } else { - i64db_remove(src->vars, num); - empty = true; - } - if (script_getvaridx(num) != 0) - script_array_update(src, num, empty); - } else { - ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name); - script_reportsrc(st); - } - return 1; - } - default: - return pc_setglobalreg_str(sd, num, str); - } - } else {// integer variable - int val = (int)__64BPRTSIZE(value); - - if(str_data[script_getvarid(num)].type == C_PARAM) { - if( pc_setparam(sd, str_data[script_getvarid(num)].val, val) == 0 ) { - if( st != NULL ) { - ShowError("script_set_reg: failed to set param '%s' to %d.\n", name, val); - script_reportsrc(st); - st->state = END; - } - return 0; } - return 1; - } + return true; + case '\'': { + struct reg_db *src = nullptr; - switch (prefix) { - case '@': - pc_setreg(sd, num, val); - return 1; - case '$': - return mapreg_setreg(num, val); - case '#': - return (name[1] == '#') ? - pc_setaccountreg2(sd, num, val) : - pc_setaccountreg(sd, num, val); - case '.': - { - struct reg_db *n = (ref) ? ref : (name[1] == '@') ? &st->stack->scope : &st->script->local; - if( n ) { - if( val != 0 ) { - i64db_iput(n->vars, num, val); - if( script_getvaridx(num) ) - script_array_update(n, num, false); - } else { - i64db_remove(n->vars, num); - if( script_getvaridx(num) ) - script_array_update(n, num, true); - } + if( ref ){ + src = ref; + }else{ + unsigned short instance_id = script_instancegetid( st ); + + if( instance_id != 0 ){ + src = &instance_data[instance_id].regs; } } - return 1; - case '\'': - { - struct reg_db *src = nullptr; - if (ref) - src = ref; - else { - unsigned short instance_id = script_instancegetid(st); - if (instance_id != 0) - src = &instance_data[instance_id].regs; + + if( src ){ + bool empty; + + if( value[0] ){ + i64db_put( src->vars, num, aStrdup( value ) ); + empty = false; + }else{ + i64db_remove( src->vars, num ); + empty = true; } - if (src) { - bool empty; - if (val != 0) { - i64db_iput(src->vars, num, val); - empty = false; - } else { - i64db_remove(src->vars, num); - empty = true; - } - if (script_getvaridx(num) != 0) - script_array_update(src, num, empty); - } else { - ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name); - script_reportsrc(st); + + if( script_getvaridx( num ) != 0 ){ + script_array_update( src, num, empty ); } - return 1; + }else{ + ShowError( "script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name ); + script_reportsrc( st ); } - default: - return pc_setglobalreg(sd, num, val); - } + + return true; + } + default: + return pc_setglobalreg_str( sd, num, value ); } } -int set_var(struct map_session_data* sd, char* name, void* val) -{ - return set_reg(NULL, sd, reference_uid(add_str(name),0), name, val, NULL); +bool set_reg_num( struct script_state* st, struct map_session_data* sd, int64 num, const char* name, int64 value, struct reg_db *ref ){ + char prefix = name[0]; + size_t vlen = 0; + + if( !script_check_RegistryVariableLength( 0, name, &vlen ) ){ + ShowError( "set_reg: Variable name length is too long (aid: %d, cid: %d): '%s' sz=%" PRIuPTR "\n", sd ? sd->status.account_id : -1, sd ? sd->status.char_id : -1, name, vlen ); + return false; + } + + if( is_string_variable( name ) ){ + // string variable + return false; + } + + if( str_data[script_getvarid(num)].type == C_PARAM ){ + if( pc_setparam( sd, str_data[script_getvarid(num)].val, value ) == 0 ){ + if( st != NULL ) { + ShowError( "script_set_reg: failed to set param '%s' to %" PRId64 ".\n", name, value ); + script_reportsrc( st ); + st->state = END; + } + + return false; + } + + return true; + } + + switch( prefix ){ + case '@': + pc_setreg( sd, num, value ); + return true; + case '$': + return mapreg_setreg( num, value ); + case '#': + return ( name[1] == '#' ) ? pc_setaccountreg2(sd, num, value) : pc_setaccountreg( sd, num, value ); + case '.': { + struct reg_db *n = ( ref ) ? ref : ( name[1] == '@' ) ? &st->stack->scope : &st->script->local; + + if( n ){ + if( value != 0 ){ + i64db_i64put( n->vars, num, value ); + + if( script_getvaridx( num ) ){ + script_array_update( n, num, false ); + } + }else{ + i64db_remove( n->vars, num ); + + if( script_getvaridx( num ) ){ + script_array_update( n, num, true ); + } + } + } + } + return true; + case '\'': { + struct reg_db *src = nullptr; + + if( ref ){ + src = ref; + }else{ + unsigned short instance_id = script_instancegetid( st ); + + if( instance_id != 0 ){ + src = &instance_data[instance_id].regs; + } + } + + if( src ){ + bool empty; + + if( value != 0 ){ + i64db_i64put( src->vars, num, value ); + empty = false; + }else{ + i64db_remove( src->vars, num ); + empty = true; + } + + if( script_getvaridx( num ) != 0 ){ + script_array_update( src, num, empty ); + } + }else{ + ShowError( "script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name ); + script_reportsrc( st ); + } + + return true; + } + default: + return pc_setglobalreg( sd, num, value ); + } } -void setd_sub(struct script_state *st, struct map_session_data *sd, const char *varname, int elem, void *value, struct reg_db *ref) -{ - set_reg(st, sd, reference_uid(add_str(varname),elem), varname, value, ref); +bool set_var_str( struct map_session_data* sd, const char* name, const char* val ){ + return set_reg_str( NULL, sd, reference_uid( add_str( name ), 0 ), name, val, NULL ); +} + +bool clear_reg( struct script_state* st, struct map_session_data* sd, int64 num, const char* name, struct reg_db *ref ){ + if( is_string_variable( name ) ){ + return set_reg_str( st, sd, num, name, "", ref ); + }else{ + return set_reg_num( st, sd, num, name, 0, ref ); + } +} + +void setd_sub_num( struct script_state* st, struct map_session_data* sd, const char* varname, int elem, int64 value, struct reg_db* ref ){ + set_reg_num( st, sd, reference_uid( add_str( varname ), elem ), varname, value, ref ); +} + +void setd_sub_str( struct script_state* st, struct map_session_data* sd, const char* varname, int elem, const char* value, struct reg_db* ref ){ + set_reg_str( st, sd, reference_uid( add_str( varname ), elem ), varname, value, ref ); } /** @@ -3314,7 +3393,7 @@ const char* conv_str(struct script_state* st, struct script_data* data) * @param data * @param sd */ -int conv_num_(struct script_state* st, struct script_data* data, struct map_session_data *sd) +int64 conv_num_(struct script_state* st, struct script_data* data, struct map_session_data *sd) { get_val_(st, data, sd); if( data_isint(data) ) @@ -3325,33 +3404,29 @@ int conv_num_(struct script_state* st, struct script_data* data, struct map_sess // the result does not overflow or underflow, it is capped instead // ex: 999999999999 is capped to INT_MAX (2147483647) char* p = data->u.str; - long num; + int64 num; + bool error; errno = 0; - num = strtol(data->u.str, NULL, 10);// change radix to 0 to support octal numbers "o377" and hex numbers "0xFF" - if( errno == ERANGE -#if LONG_MAX > INT_MAX - || num < INT_MIN || num > INT_MAX -#endif - ) - { - if( num <= INT_MIN ) - { - num = INT_MIN; - ShowError("script:conv_num: underflow detected, capping to %ld\n", num); - } - else//if( num >= INT_MAX ) - { - num = INT_MAX; - ShowError("script:conv_num: overflow detected, capping to %ld\n", num); - } + num = strtoll(data->u.str, NULL, 10);// change radix to 0 to support octal numbers "o377" and hex numbers "0xFF" + error = (errno == ERANGE); + + if( num < SCRIPT_INT_MIN || ( error && num == INT64_MIN ) ){ + num = SCRIPT_INT_MIN; + ShowError( "script:conv_num: underflow detected, capping value to %" PRId64 "", SCRIPT_INT_MIN ); + script_reportdata(data); + script_reportsrc(st); + }else if( num > SCRIPT_INT_MAX || ( error && num == INT64_MAX ) ){ + num = SCRIPT_INT_MAX; + ShowError( "script:conv_num: overflow detected, capping value to %" PRId64 "", SCRIPT_INT_MAX ); script_reportdata(data); script_reportsrc(st); } + if( data->type == C_STR ) aFree(p); data->type = C_INT; - data->u.num = (int)num; + data->u.num = num; } #if 0 // FIXME this function is being used to retrieve the position of labels and @@ -3365,12 +3440,17 @@ int conv_num_(struct script_state* st, struct script_data* data, struct map_sess data->u.num = 0; } #endif - return (int)data->u.num; + return data->u.num; +} + +int64 conv_num64(struct script_state* st, struct script_data* data) +{ + return conv_num_(st, data, NULL); } int conv_num(struct script_state* st, struct script_data* data) { - return conv_num_(st, data, NULL); + return static_cast(conv_num_(st, data, NULL)); } // @@ -3666,15 +3746,29 @@ c_op get_com(unsigned char *script,int *pos) /*========================================== * Income figures *------------------------------------------*/ -int get_num(unsigned char *script,int *pos) +int64 get_num(unsigned char *script,int *pos) { - int i,j; - i=0; j=0; - while(script[*pos]>=0xc0){ - i+=(script[(*pos)++]&0x7f)<= 0xc0; i++ ) ; // do nothing just find it + + end = i; // store the end for later + value = 0; // initialize empty value + + // If more than one byte of data exists + for( ; i > 0; i-- ){ + value |= (int64)( script[*pos+i] & (int64)0x3f ); + value <<= 6; } - return i+((script[(*pos)++]&0x7f)< i -void op_2num(struct script_state* st, int op, int i1, int i2) -{ - int ret; - double ret_double; +void op_2num( struct script_state* st, int op, int64 i1, int64 i2 ){ + int64 ret; switch( op ) { case C_AND: ret = i1 & i2; break; @@ -3770,7 +3862,7 @@ void op_2num(struct script_state* st, int op, int i1, int i2) case C_MOD: if( i2 == 0 ) { - ShowError("script:op_2num: division by zero detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2); + ShowError("script:op_2num: division by zero detected op=%s i1=%" PRId64 " i2=%" PRId64 "\n", script_op2name(op), i1, i2); script_reportsrc(st); script_pushnil(st); st->state = END; @@ -3782,25 +3874,26 @@ void op_2num(struct script_state* st, int op, int i1, int i2) ret = i1 % i2; break; default: - switch( op ) {// operators that can overflow/underflow - case C_ADD: ret = i1 + i2; ret_double = (double)i1 + (double)i2; break; - case C_SUB: ret = i1 - i2; ret_double = (double)i1 - (double)i2; break; - case C_MUL: ret = i1 * i2; ret_double = (double)i1 * (double)i2; break; + bool overflow; + + // operators that can overflow/underflow + switch( op ) { + case C_ADD: overflow = util::safe_addition( i1, i2, ret ); break; + case C_SUB: overflow = util::safe_substraction( i1, i2, ret ); break; + case C_MUL: overflow = util::safe_multiplication( i1, i2, ret ); break; default: - ShowError("script:op_2num: unexpected number operator %s i1=%d i2=%d\n", script_op2name(op), i1, i2); + ShowError("script:op_2num: unexpected number operator %s i1=%" PRId64 " i2=%" PRId64 "\n", script_op2name(op), i1, i2); script_reportsrc(st); script_pushnil(st); return; } - if( ret_double < (double)INT_MIN ) { - ShowWarning("script:op_2num: underflow detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2); + + if( overflow ){ + ShowWarning("script:op_2num: overflow detected op=%s i1=%" PRId64 " i2=%" PRId64 "\n", script_op2name(op), i1, i2); script_reportsrc(st); - ret = INT_MIN; - } - else if( ret_double > (double)INT_MAX ) { - ShowWarning("script:op_2num: overflow detected op=%s i1=%d i2=%d\n", script_op2name(op), i1, i2); - script_reportsrc(st); - ret = INT_MAX; + script_pushnil(st); + st->state = END; + return; } } script_pushint(st, ret); @@ -3857,8 +3950,8 @@ void op_2(struct script_state *st, int op) } else if( data_isint(left) && data_isint(right) ) {// ii => op_2num - int i1 = (int)left->u.num; - int i2 = (int)right->u.num; + int64 i1 = left->u.num; + int64 i2 = right->u.num; script_removetop(st, leftref.type == C_NOP ? -2 : -1, 0); op_2num(st, op, i1, i2); @@ -3885,7 +3978,6 @@ void op_2(struct script_state *st, int op) void op_1(struct script_state* st, int op) { struct script_data* data; - int i1; data = script_getdatatop(st, -1); get_val(st, data); @@ -3900,7 +3992,7 @@ void op_1(struct script_state* st, int op) return; } - i1 = (int)data->u.num; + int64 i1 = data->u.num; script_removetop(st, -1, 0); switch( op ) { @@ -3908,7 +4000,7 @@ void op_1(struct script_state* st, int op) case C_NOT: i1 = ~i1; break; case C_LNOT: i1 = !i1; break; default: - ShowError("script:op_1: unexpected operator %s i1=%d\n", script_op2name(op), i1); + ShowError("script:op_1: unexpected operator %s i1=%" PRId64 "\n", script_op2name(op), i1); script_reportsrc(st); script_pushnil(st); st->state = END; @@ -4530,8 +4622,7 @@ void script_add_autobonus(const char *autobonus) /// resets a temporary character array variable to given value -void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value) -{ +void script_cleararray_pc( struct map_session_data* sd, const char* varname ){ struct script_array *sa = NULL; struct reg_db *src = NULL; unsigned int i, *list = NULL, size = 0; @@ -4542,24 +4633,21 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void if( !(src = script_array_src(NULL,sd,varname,NULL) ) ) return; - if( value ) - script_array_ensure_zero(NULL,sd,reference_uid(key,0), NULL); - if( !(sa = static_cast(idb_get(src->arrays, key))) ) /* non-existent array, nothing to empty */ return; size = sa->size; list = script_array_cpy_list(sa); - for(i = 0; i < size; i++) { - set_reg(NULL,sd,reference_uid(key, list[i]),varname,value,NULL); + for( i = 0; i < size; i++ ){ + clear_reg( NULL, sd, reference_uid( key, list[i] ), varname, NULL ); } } /// sets a temporary character array variable element idx to given value /// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set. -void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache) +void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, int64 value, int* refcache) { int key; @@ -4570,7 +4658,7 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 key = ( refcache && refcache[0] ) ? refcache[0] : add_str(varname); - set_reg(NULL,sd,reference_uid(key, idx),varname,value,NULL); + set_reg_num( NULL, sd, reference_uid( key, idx ), varname, value, NULL ); if( refcache ) { // save to avoid repeated script->add_str calls @@ -5959,13 +6047,13 @@ BUILDIN_FUNC(input) if( is_string_variable(name) ) { int len = (int)strlen(sd->npc_str); - set_reg(st, sd, uid, name, (void*)sd->npc_str, script_getref(st,2)); + set_reg_str(st, sd, uid, name, sd->npc_str, script_getref(st,2)); script_pushint(st, (len > max ? 1 : len < min ? -1 : 0)); } else { int amount = sd->npc_amount; - set_reg(st, sd, uid, name, (void*)__64BPRTSIZE(cap_value(amount,min,max)), script_getref(st,2)); + set_reg_num(st, sd, uid, name, cap_value(amount,min,max), script_getref(st,2)); script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0)); } st->state = RUN; @@ -6044,14 +6132,14 @@ BUILDIN_FUNC(setr) if( is_string_variable(name) ) script_pushstrcopy(st,script_getstr(st, 4)); else - script_pushint(st,script_getnum(st, 4)); + script_pushint(st,script_getnum64(st, 4)); } else // Return a copy of the variable reference script_pushcopy(st, 2); if( is_string_variable(name) ) - set_reg(st,sd,num,name,(void*)script_getstr(st,3),script_getref(st,2)); + set_reg_str( st, sd, num, name, script_getstr( st, 3 ), script_getref( st, 2 ) ); else - set_reg(st,sd,num,name,(void*)__64BPRTSIZE(script_getnum(st,3)),script_getref(st,2)); + set_reg_num( st, sd, num, name, script_getnum64( st, 3 ), script_getref( st, 2 ) ); return SCRIPT_CMD_SUCCESS; } @@ -6100,12 +6188,12 @@ BUILDIN_FUNC(setarray) if( is_string_variable(name) ) {// string array for( i = 3; start < end; ++start, ++i ) - set_reg(st, sd, reference_uid(id, start), name, (void*)script_getstr(st,i), reference_getref(data)); + set_reg_str( st, sd, reference_uid( id, start ), name, script_getstr( st, i ), reference_getref( data ) ); } else {// int array for( i = 3; start < end; ++start, ++i ) - set_reg(st, sd, reference_uid(id, start), name, (void*)__64BPRTSIZE(script_getnum(st,i)), reference_getref(data)); + set_reg_num( st, sd, reference_uid( id, start ), name, script_getnum64( st, i ), reference_getref( data ) ); } return SCRIPT_CMD_SUCCESS; } @@ -6121,7 +6209,6 @@ BUILDIN_FUNC(cleararray) uint32 start; uint32 end; int32 id; - void* v; TBL_PC* sd = NULL; data = script_getdata(st, 2); @@ -6143,17 +6230,24 @@ BUILDIN_FUNC(cleararray) return SCRIPT_CMD_SUCCESS;// no player attached } - if( is_string_variable(name) ) - v = (void*)script_getstr(st, 3); - else - v = (void*)__64BPRTSIZE(script_getnum(st, 3)); - end = start + script_getnum(st, 4); if( end > SCRIPT_MAX_ARRAYSIZE ) end = SCRIPT_MAX_ARRAYSIZE; - for( ; start < end; ++start ) - set_reg(st, sd, reference_uid(id, start), name, v, script_getref(st,2)); + if( is_string_variable( name ) ){ + const char* value = script_getstr( st, 3 ); + + for( ; start < end; ++start ){ + set_reg_str( st, sd, reference_uid( id, start ), name, value, script_getref( st,2 ) ); + } + }else{ + int64 value = script_getnum64( st, 3 ); + + for( ; start < end; ++start ){ + set_reg_num( st, sd, reference_uid( id, start ), name, value, script_getref( st,2 ) ); + } + } + return SCRIPT_CMD_SUCCESS; } @@ -6171,7 +6265,6 @@ BUILDIN_FUNC(copyarray) int32 idx2; int32 id1; int32 id2; - void* v; int32 i; uint32 count; TBL_PC* sd = NULL; @@ -6194,8 +6287,9 @@ BUILDIN_FUNC(copyarray) name1 = reference_getname(data1); name2 = reference_getname(data2); - if( is_string_variable(name1) != is_string_variable(name2) ) - { + bool is_string = is_string_variable( name1 ); + + if( is_string != is_string_variable( name2 ) ){ ShowError("script:copyarray: type mismatch\n"); script_reportdata(data1); script_reportdata(data2); @@ -6215,27 +6309,32 @@ BUILDIN_FUNC(copyarray) if( count <= 0 || (id1 == id2 && idx1 == idx2) ) return SCRIPT_CMD_SUCCESS;// nothing to copy - if( id1 == id2 && idx1 > idx2 ) - {// destination might be overlapping the source - copy in reverse order - for( i = count - 1; i >= 0; --i ) - { - v = get_val2(st, reference_uid(id2, idx2 + i), reference_getref(data2)); - set_reg(st, sd, reference_uid(id1, idx1 + i), name1, v, reference_getref(data1)); - script_removetop(st, -1, 0); - } - } - else - {// normal copy - for( i = 0; i < count; ++i ) - { - if( idx2 + i < SCRIPT_MAX_ARRAYSIZE ) - { - v = get_val2(st, reference_uid(id2, idx2 + i), reference_getref(data2)); - set_reg(st, sd, reference_uid(id1, idx1 + i), name1, v, reference_getref(data1)); - script_removetop(st, -1, 0); + if( id1 == id2 && idx1 > idx2 ){ + // destination might be overlapping the source - copy in reverse order + for( i = count - 1; i >= 0; --i ){ + if( is_string ){ + const char* value = get_val2_str( st, reference_uid( id2, idx2 + i ), reference_getref( data2 ) ); + set_reg_str( st, sd, reference_uid( id1, idx1 + i ), name1, value, reference_getref( data1 ) ); + }else{ + int64 value = get_val2_num( st, reference_uid( id2, idx2 + i ), reference_getref( data2 ) ); + set_reg_num( st, sd, reference_uid( id1, idx1 + i ), name1, value, reference_getref( data1 ) ); + } + } + }else{ + // normal copy + for( i = 0; i < count; ++i ){ + if( idx2 + i < SCRIPT_MAX_ARRAYSIZE ){ + if( is_string ){ + const char* value = get_val2_str( st, reference_uid( id2, idx2 + i ), reference_getref( data2 ) ); + set_reg_str( st, sd, reference_uid( id1, idx1 + i ), name1, value, reference_getref( data1 ) ); + }else{ + int64 value = get_val2_num( st, reference_uid( id2, idx2 + i ), reference_getref( data2 ) ); + set_reg_num( st, sd, reference_uid( id1, idx1 + i ), name1, value, reference_getref( data1 ) ); + } + }else{ + // out of range - assume ""/0 + clear_reg( st, sd, reference_uid( id1, idx1 + i ), name1, reference_getref( data1 ) ); } - else// out of range - assume ""/0 - set_reg(st, sd, reference_uid(id1, idx1 + i), name1, (is_string_variable(name1)?(void*)"":(void*)0), reference_getref(data1)); } } return SCRIPT_CMD_SUCCESS; @@ -6291,7 +6390,6 @@ BUILDIN_FUNC(deletearray) TBL_PC *sd = NULL; struct script_array *sa = NULL; struct reg_db *src = NULL; - void *value; data = script_getdata(st, 2); if( !data_isreference(data) ) { @@ -6328,11 +6426,6 @@ BUILDIN_FUNC(deletearray) if( start >= end ) return SCRIPT_CMD_SUCCESS;// nothing to free - if( is_string_variable(name) ) - value = (void *)""; - else - value = (void *)0; - if( script_hasdata(st,3) ) { unsigned int count = script_getnum(st, 3); if( count > end - start ) @@ -6340,17 +6433,23 @@ BUILDIN_FUNC(deletearray) if( count <= 0 ) return SCRIPT_CMD_SUCCESS;// nothing to free + bool is_string = is_string_variable( name ); + if( end - start < sa->size ) { // Better to iterate directly on the array, no speed-up from using sa for( ; start + count < end; ++start ) { // Compact and overwrite - void* v = get_val2(st, reference_uid(id, start + count), reference_getref(data)); - set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); - script_removetop(st, -1, 0); + if( is_string ){ + const char* value = get_val2_str( st, reference_uid( id, start + count ), reference_getref( data ) ); + set_reg_str( st, sd, reference_uid( id, start ), name, value, reference_getref( data ) ); + }else{ + int64 value = get_val2_num( st, reference_uid( id, start + count ), reference_getref( data ) ); + set_reg_num( st, sd, reference_uid( id, start ), name, value, reference_getref( data ) ); + } } for( ; start < end; start++ ) { // Clean up any leftovers that weren't overwritten - set_reg(st, sd, reference_uid(id, start), name, value, reference_getref(data)); + clear_reg( st, sd, reference_uid( id, start ), name, reference_getref( data ) ); } } else { // using sa to speed up @@ -6363,16 +6462,21 @@ BUILDIN_FUNC(deletearray) for( ; i < size && list[i] < start + count; i++ ) { // Clear any entries between start and start+count, if they exist - set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data)); + clear_reg( st, sd, reference_uid( id, list[i] ), name, reference_getref( data ) ); } for( ; i < size && list[i] < end; i++ ) { // Move back count positions any entries between start+count to fill the gaps - void* v = get_val2(st, reference_uid(id, list[i]), reference_getref(data)); - set_reg(st, sd, reference_uid(id, list[i]-count), name, v, reference_getref(data)); - script_removetop(st, -1, 0); + if( is_string ){ + const char* value = get_val2_str( st, reference_uid( id, list[i] ), reference_getref( data ) ); + set_reg_str( st, sd, reference_uid( id, list[i] - count ), name, value, reference_getref( data ) ); + }else{ + int64 value = get_val2_num( st, reference_uid( id, list[i] ), reference_getref( data ) ); + set_reg_num( st, sd, reference_uid( id, list[i] - count ), name, value, reference_getref( data ) ); + } + // Clear their originals - set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data)); + clear_reg( st, sd, reference_uid( id, list[i] ), name, reference_getref( data ) ); } } } else { @@ -6382,7 +6486,7 @@ BUILDIN_FUNC(deletearray) for(i = 0; i < size; i++) { if( list[i] >= start ) // Less expensive than sorting it, most likely - set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data)); + clear_reg( st, sd, reference_uid( id, list[i] ), name, reference_getref( data ) ); } } @@ -6468,37 +6572,28 @@ BUILDIN_FUNC(inarray) } id = reference_getid(data); - if (is_string_variable(name)) - { - const char* temp; - const char* value; - value = script_getstr(st, 3); - for (i = 0; i <= array_size; ++i) - { - temp = (char*)get_val2(st, reference_uid(id, i), ref); - if (!strcmp(temp, value)) - { - script_removetop(st, -1, 0); - script_pushint(st, i); + + if( is_string_variable( name ) ){ + const char* value = script_getstr( st, 3 ); + + for( i = 0; i <= array_size; ++i ){ + const char* temp = get_val2_str( st, reference_uid( id, i ), ref ); + + if( !strcmp( temp, value ) ){ + script_pushint( st, i ); return SCRIPT_CMD_SUCCESS; } - script_removetop(st, -1, 0); } - } - else - { - int temp, value; - value = script_getnum(st, 3); - for (i = 0; i <= array_size; ++i) - { - temp = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id, i), ref)); - script_removetop(st, -1, 0); - if (temp == value) - { - script_pushint(st, i); + }else{ + int64 value = script_getnum64( st, 3 ); + + for( i = 0; i <= array_size; ++i ){ + int64 temp = get_val2_num( st, reference_uid( id, i ), ref ); + + if( temp == value ){ + script_pushint( st, i ); return SCRIPT_CMD_SUCCESS; - } - + } } } @@ -6569,46 +6664,33 @@ BUILDIN_FUNC(countinarray) id1 = reference_getid(data1); id2 = reference_getid(data2); - if (is_string_variable(name1) && is_string_variable(name2)) - { - const char* temp1; - const char* temp2; - for (; i <= array_size1; ++i) - { - temp1 = (char*)get_val2(st, reference_uid(id1, i), ref1); - for (j = reference_getindex(data2); j <= array_size2; j++) - { - temp2 = (char*)get_val2(st, reference_uid(id2, j), ref2); - if (!strcmp(temp1, temp2)) - { + + if( is_string_variable( name1 ) && is_string_variable( name2 ) ){ + for( ; i <= array_size1; ++i ){ + const char* temp1 = get_val2_str( st, reference_uid( id1, i ), ref1 ); + + for( j = reference_getindex( data2 ); j <= array_size2; j++ ){ + const char* temp2 = get_val2_str( st, reference_uid( id2, j ), ref2 ); + + if( !strcmp( temp1, temp2 ) ){ case_count++; } - script_removetop(st, -1, 0); } - script_removetop(st, -1, 0); } - } - else if (!is_string_variable(name1) && !is_string_variable(name2)) - { - int temp1, temp2; - for (; i <= array_size1; ++i) - { - temp1 = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id1, i), ref1)); - for (j = reference_getindex(data2); j <= array_size2; j++) - { - temp2 = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id2, j), ref2)); - if (temp1 == temp2) - { + }else if( !is_string_variable( name1 ) && !is_string_variable( name2 ) ){ + for( ; i <= array_size1; ++i ){ + int64 temp1 = get_val2_num( st, reference_uid( id1, i ), ref1 ); + + for( j = reference_getindex( data2 ); j <= array_size2; j++ ){ + int64 temp2 = get_val2_num( st, reference_uid( id2, j ), ref2 ); + + if( temp1 == temp2 ){ case_count++; } - script_removetop(st, -1, 0); } - script_removetop(st, -1, 0); } - } - else - { - ShowError("buildin_countinarray: Arrays does not match , You can't compare int array to string array.\n"); + }else{ + ShowError("buildin_countinarray: Arrays do not match , You can't compare an int array to a string array.\n"); script_reportdata(data1); script_reportdata(data2); st->state = END; @@ -6804,12 +6886,9 @@ static int script_getitem_randomoption(struct script_state *st, struct map_sessi opt_param_idx = reference_getindex(opt_param); for (i = 0; i < opt_id_n && i < MAX_ITEM_RDM_OPT; i++) { - it->option[i].id = static_cast((int32)__64BPRTSIZE(get_val2(st,reference_uid(opt_id_id,opt_id_idx+i),opt_id_ref))); - script_removetop(st, -1, 0); - it->option[i].value = static_cast((int32)__64BPRTSIZE(get_val2(st,reference_uid(opt_val_id,opt_val_idx+i),opt_val_ref))); - script_removetop(st, -1, 0); - it->option[i].param = static_cast((int32)__64BPRTSIZE(get_val2(st,reference_uid(opt_param_id,opt_param_idx+i),opt_param_ref))); - script_removetop(st, -1, 0); + it->option[i].id = (short)get_val2_num( st, reference_uid( opt_id_id, opt_id_idx + i ), opt_id_ref ); + it->option[i].value = (short)get_val2_num( st, reference_uid( opt_val_id, opt_val_idx + i ), opt_val_ref ); + it->option[i].param = (char)get_val2_num( st, reference_uid( opt_param_id, opt_param_idx + i ), opt_param_ref ); } return SCRIPT_CMD_SUCCESS; } @@ -7215,10 +7294,8 @@ BUILDIN_FUNC(checkweight2) slots = pc_inventoryblank(sd); for(i=0; iu.num; }else{ - value = pc_readparam(sd,script_getnum(st, 2)); + value = static_cast(pc_readparam(sd,script_getnum(st, 2))); } script_pushint(st,value); @@ -8456,19 +8533,19 @@ BUILDIN_FUNC(getpartymember) switch (type) { case 2: if (data) - setd_sub(st, NULL, varname, j, (void *)__64BPRTSIZE(p->party.member[i].account_id), data->ref); + setd_sub_num( st, NULL, varname, j, p->party.member[i].account_id, data->ref ); else mapreg_setreg(reference_uid(add_str("$@partymemberaid"), j),p->party.member[i].account_id); break; case 1: if (data) - setd_sub(st, NULL, varname, j, (void *)__64BPRTSIZE(p->party.member[i].char_id), data->ref); + setd_sub_num( st, NULL, varname, j, p->party.member[i].char_id, data->ref ); else mapreg_setreg(reference_uid(add_str("$@partymembercid"), j),p->party.member[i].char_id); break; default: if (data) - setd_sub(st, NULL, varname, j, (void *)__64BPRTSIZE(p->party.member[i].name), data->ref); + setd_sub_str( st, NULL, varname, j, p->party.member[i].name, data->ref ); else mapreg_setregstr(reference_uid(add_str("$@partymembername$"), j),p->party.member[i].name); break; @@ -11349,8 +11426,14 @@ BUILDIN_FUNC(getunits) { if (m == -1 || (m == bl->m && !x0 && !y0 && !x1 && !y1) || (bl->m == m && (bl->x >= x0 && bl->y >= y0) && (bl->x <= x1 && bl->y <= y1))) { - if (data) - set_reg(st, sd, reference_uid(id, idx + size), name, (is_string_variable(name) ? (void*)status_get_name(bl) : (void*)__64BPRTSIZE(bl->id)), reference_getref(data)); + if( data ){ + if( is_string_variable( name ) ){ + set_reg_str( st, sd, reference_uid( id, idx + size ), name, status_get_name( bl ), reference_getref( data ) ); + }else{ + set_reg_num( st, sd, reference_uid( id, idx + size ), name, bl->id, reference_getref( data ) ); + } + } + size++; } } @@ -12159,10 +12242,10 @@ BUILDIN_FUNC(getwaitingroomusers) if( nd != NULL && (cd=(struct chat_data *)map_id2bl(nd->chat_id)) != NULL ) { for(i = 0; i < cd->users; ++i) { - setd_sub(st, NULL, ".@waitingroom_users", j, (void *)__64BPRTSIZE(cd->usersd[i]->status.account_id), NULL); + setd_sub_num( st, NULL, ".@waitingroom_users", j, cd->usersd[i]->status.account_id, NULL ); j++; } - setd_sub(st, NULL, ".@waitingroom_usercount", 0, (void *)__64BPRTSIZE(j), NULL); + setd_sub_num( st, NULL, ".@waitingroom_usercount", 0, j, NULL ); } return SCRIPT_CMD_SUCCESS; } @@ -15233,7 +15316,7 @@ BUILDIN_FUNC(getmapxy) } }else sd=NULL; - set_reg(st,sd,num,name,(void*)mapname,script_getref(st,2)); + set_reg_str( st, sd, num, name, mapname, script_getref( st, 2 ) ); //Set MapX num=st->stack->stack_data[st->start+3].u.num; @@ -15247,7 +15330,7 @@ BUILDIN_FUNC(getmapxy) } }else sd=NULL; - set_reg(st,sd,num,name,(void*)__64BPRTSIZE(x),script_getref(st,3)); + set_reg_num( st, sd, num, name, x, script_getref( st, 3 ) ); //Set MapY num=st->stack->stack_data[st->start+4].u.num; @@ -15261,7 +15344,7 @@ BUILDIN_FUNC(getmapxy) } }else sd=NULL; - set_reg(st,sd,num,name,(void*)__64BPRTSIZE(y),script_getref(st,4)); + set_reg_num( st, sd, num, name, y, script_getref( st, 4 ) ); //Return Success value script_pushint(st,0); @@ -15956,7 +16039,7 @@ BUILDIN_FUNC(explode) while(str[i] != '\0') { if(str[i] == delimiter && start < SCRIPT_MAX_ARRAYSIZE-1) { //break at delimiter but ignore after reaching last array index temp[j] = '\0'; - set_reg(st, sd, reference_uid(id, start++), name, (void*)temp, reference_getref(data)); + set_reg_str( st, sd, reference_uid( id, start++ ), name, temp, reference_getref( data ) ); j = 0; ++i; } else { @@ -15966,7 +16049,7 @@ BUILDIN_FUNC(explode) //set last string temp[j] = '\0'; - set_reg(st, sd, reference_uid(id, start), name, (void*)temp, reference_getref(data)); + set_reg_str( st, sd, reference_uid( id, start ), name, temp, reference_getref( data ) ); aFree(temp); return SCRIPT_CMD_SUCCESS; @@ -16018,9 +16101,8 @@ BUILDIN_FUNC(implode) int i, k = 0; for(i = 0; i <= array_size; ++i) { - temp = (char*) get_val2(st, reference_uid(id, i), reference_getref(data)); + temp = get_val2_str( st, reference_uid( id, i ), reference_getref( data ) ); len += strlen(temp); - script_removetop(st, -1, 0); } //allocate mem @@ -16033,7 +16115,7 @@ BUILDIN_FUNC(implode) //build output for(i = 0; i < array_size; ++i) { - temp = (char*) get_val2(st, reference_uid(id, i), reference_getref(data)); + temp = get_val2_str( st, reference_uid( id, i ), reference_getref( data ) ); len = strlen(temp); memcpy(&output[k], temp, len); k += len; @@ -16042,15 +16124,12 @@ BUILDIN_FUNC(implode) memcpy(&output[k], glue, glue_len); k += glue_len; } - - script_removetop(st, -1, 0); } - temp = (char*) get_val2(st, reference_uid(id, array_size), reference_getref(data)); + temp = get_val2_str( st, reference_uid( id, array_size ), reference_getref( data ) ); len = strlen(temp); memcpy(&output[k], temp, len); k += len; - script_removetop(st, -1, 0); output[k] = '\0'; } @@ -16289,12 +16368,12 @@ BUILDIN_FUNC(sscanf){ if(sscanf(str, buf, ref_str)==0){ break; } - set_reg(st, sd, reference_uid( reference_getid(data), reference_getindex(data) ), buf_p, (void *)(ref_str), reference_getref(data)); + set_reg_str( st, sd, reference_uid( reference_getid( data ), reference_getindex( data ) ), buf_p, ref_str, reference_getref( data ) ); } else { // Number if(sscanf(str, buf, &ref_int)==0){ break; } - set_reg(st, sd, reference_uid( reference_getid(data), reference_getindex(data) ), buf_p, (void *)__64BPRTSIZE(ref_int), reference_getref(data)); + set_reg_num( st, sd, reference_uid( reference_getid( data ), reference_getindex( data ) ), buf_p, ref_int, reference_getref( data ) ); } arg++; @@ -16668,9 +16747,9 @@ BUILDIN_FUNC(setd) } if( is_string_variable(varname) ) { - setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL); + setd_sub_str( st, sd, varname, elem, script_getstr( st, 3 ), NULL ); } else { - setd_sub(st, sd, varname, elem, (void *)__64BPRTSIZE(script_getnum(st, 3)), NULL); + setd_sub_num( st, sd, varname, elem, script_getnum64( st, 3 ), NULL ); } return SCRIPT_CMD_SUCCESS; @@ -16743,10 +16822,11 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) data = script_getdata(st, j+3); name = reference_getname(data); + if( is_string_variable(name) ) - setd_sub(st, sd, name, i, (void *)(str?str:""), reference_getref(data)); + setd_sub_str( st, sd, name, i, str ? str : "", reference_getref( data ) ); else - setd_sub(st, sd, name, i, (void *)__64BPRTSIZE((str?atoi(str):0)), reference_getref(data)); + setd_sub_num( st, sd, name, i, str ? strtoll( str, nullptr, 10 ) : 0, reference_getref( data ) ); } } if( i == max_rows && max_rows < Sql_NumRows(handle) ) { @@ -17324,8 +17404,7 @@ BUILDIN_FUNC(searchitem) for( i = 0; i < count; ++start, ++i ) {// Set array - void* v = (void*)__64BPRTSIZE((int)items[i]->nameid); - set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); + set_reg_num( st, sd, reference_uid( id, start ), name, items[i]->nameid, reference_getref( data ) ); } script_pushint(st, count); @@ -17548,7 +17627,7 @@ BUILDIN_FUNC(getunitdata) return SCRIPT_CMD_FAILURE; } -#define getunitdata_sub(idx__,var__) setd_sub(st,sd,name,(idx__),(void *)__64BPRTSIZE((int)(var__)),data->ref) +#define getunitdata_sub(idx__,var__) setd_sub_num(st,sd,name,(idx__),(var__),data->ref) switch(bl->type) { case BL_MOB: @@ -19099,7 +19178,7 @@ BUILDIN_FUNC(getfreecell) }else sd = NULL; - set_reg(st, sd, num, name, (void*)__64BPRTSIZE((int)x), script_getref(st, 3)); + set_reg_num( st, sd, num, name, x, script_getref( st, 3 ) ); // Set MapY num = st->stack->stack_data[st->start + 4].u.num; @@ -19114,7 +19193,7 @@ BUILDIN_FUNC(getfreecell) }else sd = NULL; - set_reg(st, sd, num, name, (void*)__64BPRTSIZE((int)y), script_getref(st, 4)); + set_reg_num( st, sd, num, name, y, script_getref( st, 4 ) ); return SCRIPT_CMD_SUCCESS; } @@ -22054,19 +22133,19 @@ BUILDIN_FUNC(getguildmember) switch (type) { case 2: if (data) - setd_sub(st, NULL, varname, j, (void *)__64BPRTSIZE(g->member[i].account_id), data->ref); + setd_sub_num( st, NULL, varname, j, g->member[i].account_id, data->ref ); else mapreg_setreg(reference_uid(add_str("$@guildmemberaid"), j),g->member[i].account_id); break; case 1: if (data) - setd_sub(st, NULL, varname, j, (void *)__64BPRTSIZE(g->member[i].char_id), data->ref); + setd_sub_num( st, NULL, varname, j, g->member[i].char_id, data->ref ); else mapreg_setreg(reference_uid(add_str("$@guildmembercid"), j), g->member[i].char_id); break; default: if (data) - setd_sub(st, NULL, varname, j, (void *)__64BPRTSIZE(g->member[i].name), data->ref); + setd_sub_str( st, NULL, varname, j, g->member[i].name, data->ref ); else mapreg_setregstr(reference_uid(add_str("$@guildmembername$"), j), g->member[i].name); break; @@ -22629,9 +22708,9 @@ BUILDIN_FUNC(adopt) BUILDIN_FUNC(minmax){ char *functionname; unsigned int i; - int value; + int64 value; // Function pointer for our comparison function (either min or max at the moment) - int32 (*func)(int32, int32); + int64 (*func)(int64, int64); // Get the real function name functionname = script_getfuncname(st); @@ -22646,11 +22725,11 @@ BUILDIN_FUNC(minmax){ } if( strnicmp( functionname, "min", strlen( "min" ) ) == 0 ){ - value = INT_MAX; - func = i32min; + value = SCRIPT_INT_MAX; + func = i64min; }else if( strnicmp( functionname, "max", strlen( "max" ) ) == 0 ){ - value = INT_MIN; - func = i32max; + value = SCRIPT_INT_MIN; + func = i64max; }else{ ShowError( "buildin_%s: Unknown call case for min/max!\n", functionname ); st->state = END; @@ -22713,9 +22792,7 @@ BUILDIN_FUNC(minmax){ // Loop through each value stored in the array for( ; start < end; start++ ){ - value = func( value, (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ) ); - - script_removetop( st, -1, 0 ); + value = func( value, get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ) ); } } }else{ @@ -23294,7 +23371,7 @@ BUILDIN_FUNC(channel_setgroup) { id = reference_getid(data); idx = reference_getindex(data); for (i = 0; i < n; i++) { - group = (int32)__64BPRTSIZE(get_val2(st,reference_uid(id,idx+i),reference_getref(data))); + group = (int32)get_val2_num( st, reference_uid( id, idx + i ), reference_getref( data ) ); if (group == 0) { script_pushint(st,1); return SCRIPT_CMD_SUCCESS; @@ -24037,11 +24114,9 @@ BUILDIN_FUNC(mail){ } for( i = 0; i < num_items && start < end; i++, start++ ){ - msg.item[i].nameid = (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); + msg.item[i].nameid = (unsigned short)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ); msg.item[i].identify = 1; - script_removetop(st, -1, 0); - if( !itemdb_exists(msg.item[i].nameid) ){ ShowError( "buildin_mail: invalid item id %hu.\n", msg.item[i].nameid ); return SCRIPT_CMD_FAILURE; @@ -24063,9 +24138,7 @@ BUILDIN_FUNC(mail){ for( i = 0; i < num_items && start < end; i++, start++ ){ struct item_data *item = itemdb_exists(msg.item[i].nameid); - msg.item[i].amount = (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); - - script_removetop(st, -1, 0); + msg.item[i].amount = (short)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ); if( msg.item[i].amount <= 0 ){ ShowError( "buildin_mail: amount %d for item %hu is invalid.\n", msg.item[i].amount, msg.item[i].nameid ); @@ -24098,9 +24171,7 @@ BUILDIN_FUNC(mail){ } for( k = 0; k < num_items && start < end; k++, start++ ){ - msg.item[k].card[i] = (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); - - script_removetop(st, -1, 0); + msg.item[k].card[i] = (unsigned short)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ); if( msg.item[k].card[i] != 0 && !itemdb_exists(msg.item[k].card[i]) ){ ShowError( "buildin_mail: invalid card id %hu.\n", msg.item[k].card[i] ); @@ -24123,9 +24194,7 @@ BUILDIN_FUNC(mail){ } for( k = 0; k < num_items && start < end; k++, start++ ){ - msg.item[k].option[i].id = (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); - - script_removetop(st, -1, 0); + msg.item[k].option[i].id = (short)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ); } j++; @@ -24138,9 +24207,7 @@ BUILDIN_FUNC(mail){ } for( k = 0; k < num_items && start < end; k++, start++ ){ - msg.item[k].option[i].value = (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); - - script_removetop(st, -1, 0); + msg.item[k].option[i].value = (short)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ); } j++; @@ -24153,9 +24220,7 @@ BUILDIN_FUNC(mail){ } for( k = 0; k < num_items && start < end; k++, start++ ){ - msg.item[k].option[i].param = (int32)__64BPRTSIZE( get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); - - script_removetop(st, -1, 0); + msg.item[k].option[i].param = (char)get_val2_num( st, reference_uid( id, start ), reference_getref( data ) ); } } diff --git a/src/map/script.hpp b/src/map/script.hpp index 04014386d2..78cc3fb928 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -50,6 +50,7 @@ #define script_isint(st,i) data_isint(get_val(st, script_getdata(st,i))) #define script_getnum(st,val) conv_num(st, script_getdata(st,val)) +#define script_getnum64(st,val) conv_num64(st, script_getdata(st,val)) #define script_getstr(st,val) conv_str(st, script_getdata(st,val)) #define script_getref(st,val) ( script_getdata(st,val)->ref ) // Returns name of currently running function @@ -2011,9 +2012,12 @@ bool is_number(const char *p); struct script_code* parse_script(const char* src,const char* file,int line,int options); void run_script(struct script_code *rootscript,int pos,int rid,int oid); -int set_reg(struct script_state* st, struct map_session_data* sd, int64 num, const char* name, const void* value, struct reg_db *ref); -int set_var(struct map_session_data *sd, char *name, void *val); -int conv_num(struct script_state *st,struct script_data *data); +bool set_reg_num(struct script_state* st, struct map_session_data* sd, int64 num, const char* name, const int64 value, struct reg_db *ref); +bool set_reg_str(struct script_state* st, struct map_session_data* sd, int64 num, const char* name, const char* value, struct reg_db* ref); +bool set_var_str(struct map_session_data *sd, const char* name, const char* val); +bool clear_reg( struct script_state* st, struct map_session_data* sd, int64 num, const char* name, struct reg_db *ref ); +int64 conv_num64(struct script_state *st, struct script_data *data); +int conv_num(struct script_state *st, struct script_data *data); const char* conv_str(struct script_state *st,struct script_data *data); void pop_stack(struct script_state* st, int start, int end); TIMER_FUNC(run_script_timer); @@ -2034,14 +2038,14 @@ struct DBMap* script_get_userfunc_db(void); void script_run_autobonus(const char *autobonus, struct map_session_data *sd, unsigned int pos); const char* script_get_constant_str(const char* prefix, int64 value); -bool script_get_parameter(const char* name, int* value); -bool script_get_constant(const char* name, int* value); -void script_set_constant_(const char* name, int value, const char* constant_name, bool isparameter, bool deprecated); +bool script_get_parameter(const char* name, int64* value); +bool script_get_constant(const char* name, int64* value); +void script_set_constant_(const char* name, int64 value, const char* constant_name, bool isparameter, bool deprecated); #define script_set_constant(name, value, isparameter, deprecated) script_set_constant_(name, value, NULL, isparameter, deprecated) void script_hardcoded_constants(void); -void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value); -void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache); +void script_cleararray_pc(struct map_session_data* sd, const char* varname); +void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, int64 value, int* refcache); int script_config_read(const char *cfgName); void do_init_script(void); @@ -2050,8 +2054,8 @@ int add_str(const char* p); const char* get_str(int id); void script_reload(void); -// @commands (script based) -void setd_sub(struct script_state *st, struct map_session_data *sd, const char *varname, int elem, void *value, struct reg_db *ref); +void setd_sub_num( struct script_state* st, struct map_session_data* sd, const char* varname, int elem, int64 value, struct reg_db* ref ); +void setd_sub_str( struct script_state* st, struct map_session_data* sd, const char* varname, int elem, const char* value, struct reg_db* ref ); /** * Array Handling diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 836f78654c..f0c04fd24b 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -21098,16 +21098,20 @@ uint8 skill_split_atoi2(char *str, int *val, const char *delim, int min_value, u char *p = strtok(str, delim); while (p != NULL) { + int64 n_tmp; int n = min_value; trim(p); if (ISDIGIT(p[0])) // If using numeric n = atoi(p); - else if (!script_get_constant(p, &n)) { // If using constant value - ShowError("skill_split_atoi2: Invalid value: '%s'\n", p); - p = strtok(NULL, delim); - continue; + else { + if (!script_get_constant(p, &n_tmp)) { // If using constant value + ShowError("skill_split_atoi2: Invalid value: '%s'\n", p); + p = strtok(NULL, delim); + continue; + } + n = static_cast(n_tmp); } if (n > min_value) { @@ -21799,6 +21803,7 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur */ static bool skill_parse_row_skilldamage(char* split[], int columns, int current) { + int64 caster_tmp; uint16 id = 0; int caster; @@ -21815,10 +21820,11 @@ static bool skill_parse_row_skilldamage(char* split[], int columns, int current) if (ISDIGIT(split[1][0])) caster = atoi(split[1]); else { // Try to parse caster as constant - if (!script_get_constant(split[1], &caster)) { + if (!script_get_constant(split[1], &caster_tmp)) { ShowError("skill_parse_row_skilldamage: Invalid caster constant given for skill %d. Skipping.", id); return false; } + caster = static_cast(caster_tmp); } skill_db[id]->damage.caster |= caster; skill_db[id]->damage.map |= atoi(split[2]); diff --git a/src/map/status.cpp b/src/map/status.cpp index 81d40a046c..25e82888d1 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -14553,7 +14553,7 @@ void status_change_clear_onChangeMap(struct block_list *bl, struct status_change */ static bool status_readdb_status_disabled(char **str, int columns, int current) { - int type = SC_NONE; + int64 type = SC_NONE; if (ISDIGIT(str[0][0])) type = atoi(str[0]); @@ -14611,6 +14611,7 @@ static bool status_yaml_readdb_refine_sub(const YAML::Node &node, int refine_inf const YAML::Node &costs = node["Costs"]; for (const auto costit : costs) { + int64 idx_tmp = 0; const YAML::Node &type = costit; int idx = 0, price; unsigned short material; @@ -14624,8 +14625,10 @@ static bool status_yaml_readdb_refine_sub(const YAML::Node &node, int refine_inf std::string refine_cost_const = type["Type"].as(); if (ISDIGIT(refine_cost_const[0])) idx = atoi(refine_cost_const.c_str()); - else - script_get_constant(refine_cost_const.c_str(), &idx); + else { + script_get_constant(refine_cost_const.c_str(), &idx_tmp); + idx = static_cast(idx_tmp); + } price = type["Price"].as(); material = type["Material"].as(); diff --git a/src/tool/csv2yaml.cpp b/src/tool/csv2yaml.cpp index 7e7077de56..c80e9d0d95 100644 --- a/src/tool/csv2yaml.cpp +++ b/src/tool/csv2yaml.cpp @@ -80,7 +80,7 @@ std::unordered_map aegis_itemnames; std::unordered_map aegis_itemviewid; std::unordered_map aegis_mobnames; std::unordered_map aegis_skillnames; -std::unordered_map constants; +std::unordered_map constants; // Forward declaration of constant loading functions static bool parse_item_constants( const char* path ); @@ -93,7 +93,7 @@ bool askConfirmation( const char* fmt, ... ); YAML::Emitter body; // Implement the function instead of including the original version by linking -void script_set_constant_( const char* name, int value, const char* constant_name, bool isparameter, bool deprecated ){ +void script_set_constant_( const char* name, int64 value, const char* constant_name, bool isparameter, bool deprecated ){ constants[name] = value; }