Skip to content

Commit

Permalink
Added int64 support to the script engine (#4522)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Lemongrass3110 committed Jan 13, 2020
1 parent 3142863 commit e72c736
Show file tree
Hide file tree
Showing 41 changed files with 942 additions and 677 deletions.
2 changes: 1 addition & 1 deletion conf/msg_conf/map_msg.conf
Expand Up @@ -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.

Expand Down
4 changes: 2 additions & 2 deletions conf/msg_conf/map_msg_chn.conf
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions conf/msg_conf/map_msg_frn.conf
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion conf/msg_conf/map_msg_idn.conf
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions conf/msg_conf/map_msg_por.conf
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions conf/msg_conf/map_msg_rus.conf
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion conf/msg_conf/map_msg_spn.conf
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion conf/msg_conf/map_msg_tha.conf
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions sql-files/main.sql
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions 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';
19 changes: 9 additions & 10 deletions src/char/char_logif.cpp
Expand Up @@ -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;

Expand All @@ -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;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/char/char_logif.hpp
Expand Up @@ -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);
Expand Down
68 changes: 33 additions & 35 deletions src/char/inter.cpp
Expand Up @@ -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);
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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:
Expand All @@ -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));
Expand Down
1 change: 0 additions & 1 deletion src/char/inter.hpp
Expand Up @@ -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 */
31 changes: 31 additions & 0 deletions src/common/db.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down

2 comments on commit e72c736

@mazvi
Copy link
Contributor

@mazvi mazvi commented on e72c736 Jan 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bigint 11 on sql? Why not 20?

@Atemo
Copy link
Contributor

@Atemo Atemo commented on e72c736 Jan 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

11 or 20 doesn't change anything here

Please sign in to comment.