From e72c7360cf9108b9aa5b5ad7891f8a8dcf16af49 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Mon, 13 Jan 2020 14:44:48 +0100 Subject: [PATCH] Added int64 support to the script engine (#4522) Added support for signed 64 bit integer value computation into the script engine. This is required because newer official features require support for bigger numbers inside the scripts. This also cleans up a lot of messy code and fixes a few issues like script stack corruptions. Thanks to @aleos89 and everyone who supported me with this. --- conf/msg_conf/map_msg.conf | 2 +- conf/msg_conf/map_msg_chn.conf | 4 +- conf/msg_conf/map_msg_frn.conf | 4 +- conf/msg_conf/map_msg_idn.conf | 2 +- conf/msg_conf/map_msg_por.conf | 4 +- conf/msg_conf/map_msg_rus.conf | 4 +- conf/msg_conf/map_msg_spn.conf | 2 +- conf/msg_conf/map_msg_tha.conf | 2 +- sql-files/main.sql | 6 +- sql-files/upgrades/upgrade_20200109.sql | 8 + src/char/char_logif.cpp | 19 +- src/char/char_logif.hpp | 2 +- src/char/inter.cpp | 68 +- src/char/inter.hpp | 1 - src/common/db.cpp | 31 + src/common/db.hpp | 36 + src/common/mmo.hpp | 2 +- src/common/utilities.cpp | 68 ++ src/common/utilities.hpp | 4 + src/login/account.cpp | 30 +- src/login/account.hpp | 4 +- src/map/achievement.cpp | 2 +- src/map/atcommand.cpp | 17 +- src/map/channel.cpp | 3 +- src/map/clif.cpp | 2 +- src/map/duel.cpp | 2 +- src/map/intif.cpp | 16 +- src/map/itemdb.cpp | 30 +- src/map/map.cpp | 2 +- src/map/mapreg.cpp | 34 +- src/map/mapreg.hpp | 6 +- src/map/mob.cpp | 33 +- src/map/npc.cpp | 63 +- src/map/npc_chat.cpp | 22 +- src/map/pc.cpp | 108 +-- src/map/pc.hpp | 16 +- src/map/script.cpp | 919 +++++++++++++----------- src/map/script.hpp | 24 +- src/map/skill.cpp | 16 +- src/map/status.cpp | 9 +- src/tool/csv2yaml.cpp | 4 +- 41 files changed, 948 insertions(+), 683 deletions(-) create mode 100644 sql-files/upgrades/upgrade_20200109.sql 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; }