From 01f61cfa4f750ff74be54fa5793ea9df921da181 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Fri, 21 Dec 2018 00:02:19 +0100 Subject: [PATCH] Added support for 64bit ticks (#3768) Fixes #3017 Thanks to Hercules for the idea and their implementation of it. This deprecates Windows XP support. If you want to use it to run your server on it, you have to forcefully enable it now. Since 64bit ticks do not exist on XP, you might encounter some issues that are already fixed on other OS. --- sql-files/main.sql | 10 +- sql-files/upgrades/upgrade_20181220.sql | 9 + src/char/char.cpp | 2 - src/char/char_mapif.cpp | 13 +- src/char/int_auction.cpp | 6 +- src/char/int_elemental.cpp | 6 +- src/char/int_mercenary.cpp | 6 +- src/char/inter.cpp | 8 +- src/common/core.cpp | 2 +- src/common/mmo.hpp | 12 +- src/common/socket.cpp | 8 +- src/common/socket.hpp | 3 +- src/common/timer.cpp | 42 ++--- src/common/timer.hpp | 30 ++-- src/common/winapi.hpp | 6 + src/config/core.hpp | 6 + src/login/login.cpp | 4 +- src/map/atcommand.cpp | 9 +- src/map/battle.cpp | 14 +- src/map/battle.hpp | 6 +- src/map/channel.cpp | 2 +- src/map/chrif.cpp | 6 +- src/map/chrif.hpp | 3 +- src/map/clif.cpp | 98 +++++------ src/map/clif.hpp | 23 +-- src/map/elemental.cpp | 12 +- src/map/elemental.hpp | 6 +- src/map/map.cpp | 2 +- src/map/map.hpp | 4 +- src/map/mercenary.cpp | 2 +- src/map/mercenary.hpp | 2 +- src/map/mob.cpp | 45 ++--- src/map/mob.hpp | 12 +- src/map/npc.cpp | 20 ++- src/map/npc.hpp | 9 +- src/map/pc.cpp | 38 ++--- src/map/pc.hpp | 44 ++--- src/map/pet.cpp | 8 +- src/map/pet.hpp | 2 +- src/map/script.cpp | 7 +- src/map/skill.cpp | 102 ++++++------ src/map/skill.hpp | 34 ++-- src/map/status.cpp | 210 +++++++++++++----------- src/map/status.hpp | 6 +- src/map/unit.cpp | 12 +- src/map/unit.hpp | 8 +- 46 files changed, 495 insertions(+), 424 deletions(-) create mode 100644 sql-files/upgrades/upgrade_20181220.sql diff --git a/sql-files/main.sql b/sql-files/main.sql index 58619424fa..55e355de4b 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -109,7 +109,7 @@ CREATE TABLE IF NOT EXISTS `db_roulette` ( CREATE TABLE IF NOT EXISTS `bonus_script` ( `char_id` INT(11) UNSIGNED NOT NULL, `script` TEXT NOT NULL, - `tick` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `tick` BIGINT(20) NOT NULL DEFAULT '0', `flag` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0', `type` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', `icon` SMALLINT(3) NOT NULL DEFAULT '-1' @@ -375,7 +375,7 @@ CREATE TABLE IF NOT EXISTS `elemental` ( `mdef` smallint(4) unsigned NOT NULL default '0', `flee` smallint(4) unsigned NOT NULL default '0', `hit` smallint(4) unsigned NOT NULL default '0', - `life_time` int(11) NOT NULL default '0', + `life_time` bigint(20) NOT NULL default '0', PRIMARY KEY (`ele_id`) ) ENGINE=MyISAM; @@ -873,7 +873,7 @@ CREATE TABLE IF NOT EXISTS `mercenary` ( `hp` int(11) unsigned NOT NULL default '0', `sp` int(11) unsigned NOT NULL default '0', `kill_counter` int(11) NOT NULL, - `life_time` int(11) NOT NULL default '0', + `life_time` bigint(20) NOT NULL default '0', PRIMARY KEY (`mer_id`) ) ENGINE=MyISAM; @@ -913,7 +913,7 @@ CREATE TABLE IF NOT EXISTS `sc_data` ( `account_id` int(11) unsigned NOT NULL, `char_id` int(11) unsigned NOT NULL, `type` smallint(11) unsigned NOT NULL, - `tick` int(11) NOT NULL, + `tick` bigint(20) NOT NULL, `val1` int(11) NOT NULL default '0', `val2` int(11) NOT NULL default '0', `val3` int(11) NOT NULL default '0', @@ -930,7 +930,7 @@ CREATE TABLE IF NOT EXISTS `skillcooldown` ( `account_id` int(11) unsigned NOT NULL, `char_id` int(11) unsigned NOT NULL, `skill` smallint(11) unsigned NOT NULL DEFAULT '0', - `tick` int(11) NOT NULL, + `tick` bigint(20) NOT NULL, KEY `account_id` (`account_id`), KEY `char_id` (`char_id`) ) ENGINE=MyISAM; diff --git a/sql-files/upgrades/upgrade_20181220.sql b/sql-files/upgrades/upgrade_20181220.sql new file mode 100644 index 0000000000..cbae2f5af4 --- /dev/null +++ b/sql-files/upgrades/upgrade_20181220.sql @@ -0,0 +1,9 @@ +ALTER TABLE `bonus_script` MODIFY COLUMN `tick` bigint(20) NOT NULL default '0'; + +ALTER TABLE `elemental` MODIFY COLUMN `life_time` bigint(20) NOT NULL default '0'; + +ALTER TABLE `mercenary` MODIFY COLUMN `life_time` bigint(20) NOT NULL default '0'; + +ALTER TABLE `sc_data` MODIFY COLUMN `tick` bigint(20) NOT NULL; + +ALTER TABLE `skillcooldown` MODIFY COLUMN `tick` bigint(20) NOT NULL; diff --git a/src/char/char.cpp b/src/char/char.cpp index 9d03d3ccc0..855b3544fb 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -67,8 +67,6 @@ struct s_subnet { } subnet[16]; int subnet_count = 0; -TIMER_FUNC(char_chardb_waiting_disconnect); - DBMap* auth_db; // uint32 account_id -> struct auth_node* DBMap* online_char_db; // uint32 account_id -> struct online_char_data* DBMap* char_db_; // uint32 char_id -> struct mmo_charstatus* diff --git a/src/char/char_mapif.cpp b/src/char/char_mapif.cpp index 7c0fe9e8ad..982dd93148 100644 --- a/src/char/char_mapif.cpp +++ b/src/char/char_mapif.cpp @@ -11,6 +11,7 @@ #include "../common/socket.hpp" #include "../common/sql.hpp" #include "../common/strlib.hpp" +#include "../common/timer.hpp" #include "char.hpp" #include "char_logif.hpp" @@ -297,7 +298,7 @@ int chmapif_parse_askscdata(int fd){ for( count = 0; count < 50 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count ) { Sql_GetData(sql_handle, 0, &data, NULL); scdata.type = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); scdata.tick = atoi(data); + Sql_GetData(sql_handle, 1, &data, NULL); scdata.tick = strtoll( data, nullptr, 10 ); Sql_GetData(sql_handle, 2, &data, NULL); scdata.val1 = atoi(data); Sql_GetData(sql_handle, 3, &data, NULL); scdata.val2 = atoi(data); Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data); @@ -512,7 +513,7 @@ int chmapif_parse_req_saveskillcooldown(int fd){ memcpy(&data,RFIFOP(fd,14+i*sizeof(struct skill_cooldown_data)),sizeof(struct skill_cooldown_data)); if( i > 0 ) StringBuf_AppendStr(&buf, ", "); - StringBuf_Printf(&buf, "('%d','%d','%d','%d')", aid, cid, data.skill_id, data.tick); + StringBuf_Printf(&buf, "('%d','%d','%d','%" PRtf "')", aid, cid, data.skill_id, data.tick); } if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) Sql_ShowDebug(sql_handle); @@ -551,7 +552,7 @@ int chmapif_parse_req_skillcooldown(int fd){ for( count = 0; count < MAX_SKILLCOOLDOWN && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count ) { Sql_GetData(sql_handle, 0, &data, NULL); scd.skill_id = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); scd.tick = atoi(data); + Sql_GetData(sql_handle, 1, &data, NULL); scd.tick = strtoll( data, nullptr, 10 ); memcpy(WFIFOP(fd,14+count*sizeof(struct skill_cooldown_data)), &scd, sizeof(struct skill_cooldown_data)); } if( count >= MAX_SKILLCOOLDOWN ) @@ -967,7 +968,7 @@ int chmapif_parse_save_scdata(int fd){ memcpy (&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data)); if( i > 0 ) StringBuf_AppendStr(&buf, ", "); - StringBuf_Printf(&buf, "('%d','%d','%hu','%d','%ld','%ld','%ld','%ld')", aid, cid, + StringBuf_Printf(&buf, "('%d','%d','%hu','%" PRtf "','%ld','%ld','%ld','%ld')", aid, cid, data.type, data.tick, data.val1, data.val2, data.val3, data.val4); } if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ) @@ -1295,7 +1296,7 @@ int chmapif_bonus_script_get(int fd) { schema_config.bonus_script_db, cid, MAX_PC_BONUS_SCRIPT) || SQL_ERROR == SqlStmt_Execute(stmt) || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &tmp_bsdata.script_str, sizeof(tmp_bsdata.script_str), NULL, NULL) || - SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UINT32, &tmp_bsdata.tick, 0, NULL, NULL) || + SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT64, &tmp_bsdata.tick, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT16, &tmp_bsdata.flag, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_UINT8, &tmp_bsdata.type, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_INT16, &tmp_bsdata.icon, 0, NULL, NULL) @@ -1372,7 +1373,7 @@ int chmapif_bonus_script_save(int fd) { Sql_EscapeString(sql_handle, esc_script, bsdata.script_str); if (i > 0) StringBuf_AppendStr(&buf,", "); - StringBuf_Printf(&buf, "('%d','%s','%d','%d','%d','%d')", cid, esc_script, bsdata.tick, bsdata.flag, bsdata.type, bsdata.icon); + StringBuf_Printf(&buf, "('%d','%s','%" PRtf "','%d','%d','%d')", cid, esc_script, bsdata.tick, bsdata.flag, bsdata.type, bsdata.icon); } if (SQL_ERROR == Sql_QueryStr(sql_handle,StringBuf_Value(&buf))) Sql_ShowDebug(sql_handle); diff --git a/src/char/int_auction.cpp b/src/char/int_auction.cpp index c514f59db3..b268ebab47 100644 --- a/src/char/int_auction.cpp +++ b/src/char/int_auction.cpp @@ -120,7 +120,7 @@ unsigned int auction_create(struct auction_data *auction) else { struct auction_data *auction_; - unsigned int tick = auction->hours * 3600000; + t_tick tick = auction->hours * 3600000; auction->item.amount = 1; auction->item.identify = 1; @@ -128,7 +128,7 @@ unsigned int auction_create(struct auction_data *auction) auction->auction_id = (unsigned int)SqlStmt_LastInsertId(stmt); auction->auction_end_timer = add_timer( gettick() + tick , auction_end_timer, auction->auction_id, 0); - ShowInfo("New Auction %u | time left %u ms | By %s.\n", auction->auction_id, tick, auction->seller_name); + ShowInfo("New Auction %u | time left %" PRtf " ms | By %s.\n", auction->auction_id, tick, auction->seller_name); CREATE(auction_, struct auction_data, 1); memcpy(auction_, auction, sizeof(struct auction_data)); @@ -191,7 +191,7 @@ void inter_auctions_fromsql(void) int i; char *data; StringBuf buf; - unsigned int tick = gettick(), endtick; + t_tick tick = gettick(), endtick; time_t now = time(NULL); StringBuf_Init(&buf); diff --git a/src/char/int_elemental.cpp b/src/char/int_elemental.cpp index 30fe46ff39..2eb3454d3e 100644 --- a/src/char/int_elemental.cpp +++ b/src/char/int_elemental.cpp @@ -21,7 +21,7 @@ bool mapif_elemental_save(struct s_elemental* ele) { if( ele->elemental_id == 0 ) { // Create new DB entry if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`atk1`,`atk2`,`matk`,`aspd`,`def`,`mdef`,`flee`,`hit`,`life_time`)" - "VALUES ('%d','%d','%d','%u','%u','%u','%u','%d','%d','%d','%d','%d','%d','%d','%d','%u')", + "VALUES ('%d','%d','%d','%u','%u','%u','%u','%d','%d','%d','%d','%d','%d','%d','%d','%" PRtf "')", schema_config.elemental_db, ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2, ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time) ) { Sql_ShowDebug(sql_handle); @@ -32,7 +32,7 @@ bool mapif_elemental_save(struct s_elemental* ele) { } else if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%u', `sp` = '%u'," "`max_hp` = '%u', `max_sp` = '%u', `atk1` = '%d', `atk2` = '%d', `matk` = '%d', `aspd` = '%d', `def` = '%d'," - "`mdef` = '%d', `flee` = '%d', `hit` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'", schema_config.elemental_db, + "`mdef` = '%d', `flee` = '%d', `hit` = '%d', `life_time` = '%" PRtf "' WHERE `ele_id` = '%d'", schema_config.elemental_db, ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->atk, ele->atk2, ele->matk, ele->amotion, ele->def, ele->mdef, ele->flee, ele->hit, ele->life_time, ele->elemental_id) ) { // Update DB entry @@ -75,7 +75,7 @@ bool mapif_elemental_load(int ele_id, uint32 char_id, struct s_elemental *ele) { Sql_GetData(sql_handle, 11, &data, NULL); ele->mdef = atoi(data); Sql_GetData(sql_handle, 12, &data, NULL); ele->flee = atoi(data); Sql_GetData(sql_handle, 13, &data, NULL); ele->hit = atoi(data); - Sql_GetData(sql_handle, 14, &data, NULL); ele->life_time = atoi(data); + Sql_GetData(sql_handle, 14, &data, NULL); ele->life_time = strtoll( data, nullptr, 10 ); Sql_FreeResult(sql_handle); if( charserv_config.save_log ) ShowInfo("Elemental loaded (ID: %d / Class: %d / CID: %d).\n", ele->elemental_id, ele->class_, ele->char_id); diff --git a/src/char/int_mercenary.cpp b/src/char/int_mercenary.cpp index 117d6f9a94..ae5347bbcd 100644 --- a/src/char/int_mercenary.cpp +++ b/src/char/int_mercenary.cpp @@ -73,7 +73,7 @@ bool mapif_mercenary_save(struct s_mercenary* merc) if( merc->mercenary_id == 0 ) { // Create new DB entry if( SQL_ERROR == Sql_Query(sql_handle, - "INSERT INTO `%s` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%u','%u','%u','%u')", + "INSERT INTO `%s` (`char_id`,`class`,`hp`,`sp`,`kill_counter`,`life_time`) VALUES ('%d','%d','%u','%u','%u','%" PRtf "')", schema_config.mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time) ) { Sql_ShowDebug(sql_handle); @@ -83,7 +83,7 @@ bool mapif_mercenary_save(struct s_mercenary* merc) merc->mercenary_id = (int)Sql_LastInsertId(sql_handle); } else if( SQL_ERROR == Sql_Query(sql_handle, - "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `hp` = '%u', `sp` = '%u', `kill_counter` = '%u', `life_time` = '%u' WHERE `mer_id` = '%d'", + "UPDATE `%s` SET `char_id` = '%d', `class` = '%d', `hp` = '%u', `sp` = '%u', `kill_counter` = '%u', `life_time` = '%" PRtf "' WHERE `mer_id` = '%d'", schema_config.mercenary_db, merc->char_id, merc->class_, merc->hp, merc->sp, merc->kill_count, merc->life_time, merc->mercenary_id) ) { // Update DB entry Sql_ShowDebug(sql_handle); @@ -117,7 +117,7 @@ bool mapif_mercenary_load(int merc_id, uint32 char_id, struct s_mercenary *merc) Sql_GetData(sql_handle, 1, &data, NULL); merc->hp = atoi(data); Sql_GetData(sql_handle, 2, &data, NULL); merc->sp = atoi(data); Sql_GetData(sql_handle, 3, &data, NULL); merc->kill_count = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); merc->life_time = atoi(data); + Sql_GetData(sql_handle, 4, &data, NULL); merc->life_time = strtoll( data, nullptr, 10 ); Sql_FreeResult(sql_handle); if( charserv_config.save_log ) ShowInfo("Mercenary loaded (ID: %d / Class: %d / CID: %d).\n", merc->mercenary_id, merc->class_, merc->char_id); diff --git a/src/char/inter.cpp b/src/char/inter.cpp index 5fde70c12c..cc0b68b140 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -66,7 +66,7 @@ int inter_recv_packet_length[] = { struct WisData { int id, fd, count, len, gmlvl; - unsigned long tick; + t_tick tick; char src[NAME_LENGTH], dst[NAME_LENGTH], msg[512]; }; static DBMap* wis_db = NULL; // int wis_id -> struct WisData* @@ -1100,9 +1100,9 @@ int mapif_disconnectplayer(int fd, uint32 account_id, uint32 char_id, int reason */ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) { - unsigned long tick; + t_tick tick; struct WisData *wd = (struct WisData *)db_data2ptr(data); - tick = va_arg(ap, unsigned long); + tick = va_arg(ap, t_tick); if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX) wis_dellist[wis_delnum++] = wd->id; @@ -1112,7 +1112,7 @@ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) int check_ttl_wisdata(void) { - unsigned long tick = gettick(); + t_tick tick = gettick(); int i; do { diff --git a/src/common/core.cpp b/src/common/core.cpp index c251242b50..d1cd123f09 100644 --- a/src/common/core.cpp +++ b/src/common/core.cpp @@ -364,7 +364,7 @@ int main (int argc, char **argv) // Main runtime cycle while (runflag != CORE_ST_STOP) { - int next = do_timer(gettick_nocache()); + t_tick next = do_timer(gettick_nocache()); do_sockets(next); } diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index f0962518e6..00fba05c16 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -10,6 +10,7 @@ #include "cbasetypes.hpp" #include "db.hpp" +#include "timer.hpp" // t_tick #ifndef PACKETVER #error Please define PACKETVER in src/config/packets.hpp @@ -332,13 +333,14 @@ struct script_reg_str { //For saving status changes across sessions. [Skotlex] struct status_change_data { unsigned short type; //SC_type - long val1, val2, val3, val4, tick; //Remaining duration. + long val1, val2, val3, val4; + t_tick tick; //Remaining duration. }; #define MAX_BONUS_SCRIPT_LENGTH 512 struct bonus_script_data { char script_str[MAX_BONUS_SCRIPT_LENGTH]; //< Script string - uint32 tick; ///< Tick + t_tick tick; ///< Tick uint16 flag; ///< Flags @see enum e_bonus_script_flags int16 icon; ///< Icon SI uint8 type; ///< 0 - None, 1 - Buff, 2 - Debuff @@ -346,7 +348,7 @@ struct bonus_script_data { struct skill_cooldown_data { unsigned short skill_id; - long tick; + t_tick tick; }; enum storage_type { @@ -445,7 +447,7 @@ struct s_mercenary { short class_; int hp, sp; unsigned int kill_count; - unsigned int life_time; + t_tick life_time; }; struct s_elemental { @@ -455,7 +457,7 @@ struct s_elemental { enum e_mode mode; int hp, sp, max_hp, max_sp, matk, atk, atk2; short hit, flee, amotion, def, mdef; - int life_time; + t_tick life_time; }; struct s_friend { diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 9a8e90d9de..1a1f338bea 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -819,7 +819,7 @@ int WFIFOSET(int fd, size_t len) return 0; } -int do_sockets(int next) +int do_sockets(t_tick next) { fd_set rfd; struct timeval timeout; @@ -841,8 +841,8 @@ int do_sockets(int next) #endif // can timeout until the next tick - timeout.tv_sec = next/1000; - timeout.tv_usec = next%1000*1000; + timeout.tv_sec = (long)(next/1000); + timeout.tv_usec = (long)(next%1000*1000); memcpy(&rfd, &readfds, sizeof(rfd)); ret = sSelect(fd_max, &rfd, NULL, NULL, &timeout); @@ -955,7 +955,7 @@ int do_sockets(int next) typedef struct _connect_history { struct _connect_history* next; uint32 ip; - uint32 tick; + t_tick tick; int count; unsigned ddos : 1; } ConnectHistory; diff --git a/src/common/socket.hpp b/src/common/socket.hpp index 88d967f43f..ec18e7c493 100644 --- a/src/common/socket.hpp +++ b/src/common/socket.hpp @@ -15,6 +15,7 @@ #include #include "cbasetypes.hpp" +#include "timer.hpp" // t_tick #define FIFOSIZE_SERVERLINK 256*1024 @@ -124,7 +125,7 @@ int realloc_writefifo(int fd, size_t addition); int WFIFOSET(int fd, size_t len); int RFIFOSKIP(int fd, size_t len); -int do_sockets(int next); +int do_sockets(t_tick next); void do_close(int fd); void socket_init(void); void socket_final(void); diff --git a/src/common/timer.cpp b/src/common/timer.cpp index 36f3322dda..b1e032812b 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp @@ -22,8 +22,8 @@ // or many connected clients, please increase TIMER_MIN_INTERVAL. // The official interval of 20ms is however strongly recommended, // as it is needed for perfect server-client syncing. -#define TIMER_MIN_INTERVAL 20 -#define TIMER_MAX_INTERVAL 1000 +const t_tick TIMER_MIN_INTERVAL = 20; +const t_tick TIMER_MAX_INTERVAL = 1000; // timers (array) static struct TimerData* timer_data = NULL; @@ -137,10 +137,14 @@ static void rdtsc_calibrate(){ #endif /// platform-abstracted tick retrieval -static unsigned int tick(void) +static t_tick tick(void) { #if defined(WIN32) +#ifdef DEPRECATED_WINDOWS_SUPPORT return GetTickCount(); +#else + return GetTickCount64(); +#endif #elif defined(ENABLE_RDTSC) // return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK); @@ -160,7 +164,7 @@ static unsigned int tick(void) #if defined(TICK_CACHE) && TICK_CACHE > 1 ////////////////////////////////////////////////////////////////////////// // tick is cached for TICK_CACHE calls -static unsigned int gettick_cache; +static t_tick gettick_cache; static int gettick_count = 1; unsigned int gettick_nocache(void) @@ -170,7 +174,7 @@ unsigned int gettick_nocache(void) return gettick_cache; } -unsigned int gettick(void) +t_tick gettick(void) { return ( --gettick_count == 0 ) ? gettick_nocache() : gettick_cache; } @@ -178,12 +182,12 @@ unsigned int gettick(void) #else ////////////////////////////// // tick doesn't get cached -unsigned int gettick_nocache(void) +t_tick gettick_nocache(void) { return tick(); } -unsigned int gettick(void) +t_tick gettick(void) { return tick(); } @@ -240,7 +244,7 @@ static int acquire_timer(void) /// Starts a new timer that is deleted once it expires (single-use). /// Returns the timer's id. -int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data) +int add_timer(t_tick tick, TimerFunc func, int id, intptr_t data) { int tid; @@ -258,13 +262,13 @@ int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data) /// Starts a new timer that automatically restarts itself (infinite loop until manually removed). /// Returns the timer's id, or INVALID_TIMER if it fails. -int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval) +int add_timer_interval(t_tick tick, TimerFunc func, int id, intptr_t data, int interval) { int tid; if( interval < 1 ) { - ShowError("add_timer_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick())); + ShowError("add_timer_interval: invalid interval (tick=%" PRtf " %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick())); return INVALID_TIMER; } @@ -310,14 +314,14 @@ int delete_timer(int tid, TimerFunc func) /// Adjusts a timer's expiration time. /// Returns the new tick value, or -1 if it fails. -int addtick_timer(int tid, unsigned int tick) +t_tick addt_tickimer(int tid, t_tick tick) { - return settick_timer(tid, timer_data[tid].tick+tick); + return sett_tickimer(tid, timer_data[tid].tick+tick); } /// Modifies a timer's expiration time (an alternative to deleting a timer and starting a new one). /// Returns the new tick value, or -1 if it fails. -int settick_timer(int tid, unsigned int tick) +t_tick sett_tickimer(int tid, t_tick tick) { size_t i; @@ -325,28 +329,28 @@ int settick_timer(int tid, unsigned int tick) ARR_FIND(0, BHEAP_LENGTH(timer_heap), i, BHEAP_DATA(timer_heap)[i] == tid); if( i == BHEAP_LENGTH(timer_heap) ) { - ShowError("settick_timer: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + ShowError("sett_tickimer: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); return -1; } - if( (int)tick == -1 ) + if( tick == -1 ) tick = 0;// add 1ms to avoid the error value -1 if( timer_data[tid].tick == tick ) - return (int)tick;// nothing to do, already in propper position + return tick;// nothing to do, already in propper position // pop and push adjusted timer BHEAP_POPINDEX(timer_heap, i, DIFFTICK_MINTOPCMP, SWAP); timer_data[tid].tick = tick; BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP, SWAP); - return (int)tick; + return tick; } /// Executes all expired timers. /// Returns the value of the smallest non-expired timer (or 1 second if there aren't any). -int do_timer(unsigned int tick) +t_tick do_timer(t_tick tick) { - int diff = TIMER_MAX_INTERVAL; // return value + t_tick diff = TIMER_MAX_INTERVAL; // return value // process all timers one by one while( BHEAP_LENGTH(timer_heap) ) diff --git a/src/common/timer.hpp b/src/common/timer.hpp index 3d0709bf0a..127ddd1b00 100644 --- a/src/common/timer.hpp +++ b/src/common/timer.hpp @@ -8,9 +8,17 @@ #include "cbasetypes.hpp" -#define DIFF_TICK(a,b) ((int)((a)-(b))) +typedef int64 t_tick; +#define PRtf PRId64 -const int32 INFINITE_TICK = -1; +static inline t_tick tick_diff( t_tick a, t_tick b ){ + return a - b; +} + +// Convenience for now +#define DIFF_TICK(a,b) tick_diff(a,b) + +const t_tick INFINITE_TICK = -1; #define INVALID_TIMER -1 #define CLIF_WALK_TIMER -2 @@ -22,13 +30,13 @@ enum { TIMER_REMOVE_HEAP = 0x10, }; -#define TIMER_FUNC(x) int x ( int tid, unsigned int tick, int id, intptr_t data ) +#define TIMER_FUNC(x) int x ( int tid, t_tick tick, int id, intptr_t data ) // Struct declaration typedef TIMER_FUNC((*TimerFunc)); struct TimerData { - unsigned int tick; + t_tick tick; TimerFunc func; unsigned int type; int interval; @@ -40,16 +48,16 @@ struct TimerData { // Function prototype declaration -unsigned int gettick(void); -unsigned int gettick_nocache(void); +t_tick gettick(void); +t_tick gettick_nocache(void); -int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data); -int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); +int add_timer(t_tick tick, TimerFunc func, int id, intptr_t data); +int add_timer_interval(t_tick tick, TimerFunc func, int id, intptr_t data, int interval); const struct TimerData* get_timer(int tid); int delete_timer(int tid, TimerFunc func); -int addtick_timer(int tid, unsigned int tick); -int settick_timer(int tid, unsigned int tick); +t_tick addt_tickimer(int tid, t_tick tick); +t_tick sett_tickimer(int tid, t_tick tick); int add_timer_func_list(TimerFunc func, const char* name); @@ -60,7 +68,7 @@ const char* timestamp2string(char* str, size_t size, time_t timestamp, const cha void split_time(int time, int* year, int* month, int* day, int* hour, int* minute, int* second); double solve_time(char* modif_p); -int do_timer(unsigned int tick); +t_tick do_timer(t_tick tick); void timer_init(void); void timer_final(void); diff --git a/src/common/winapi.hpp b/src/common/winapi.hpp index f43cd4af1d..b3ea895a00 100644 --- a/src/common/winapi.hpp +++ b/src/common/winapi.hpp @@ -4,6 +4,9 @@ #ifndef WINAPI_HPP #define WINAPI_HPP +#include "../config/core.hpp" + +#ifdef DEPRECATED_WINDOWS_SUPPORT #ifndef NTDDI_VERSION #define NTDDI_VERSION 0x05000000 // Windows 2000 #endif @@ -19,6 +22,9 @@ #ifndef _WIN32_WINNT_VISTA #define _WIN32_WINNT_VISTA 0x0600 // Windows Vista #endif +#else +#include +#endif #define STRICT #define WIN32_LEAN_AND_MEAN diff --git a/src/config/core.hpp b/src/config/core.hpp index a9b53a13d7..9020de4696 100644 --- a/src/config/core.hpp +++ b/src/config/core.hpp @@ -68,6 +68,12 @@ /// Comment to disable warnings for deprecated script constants #define SCRIPT_CONSTANT_DEPRECATION +// Uncomment to enable deprecated support for Windows XP and lower +// Note: +// Windows XP still has 32bit ticks. This means you need to restart your operating system before time +// overflows, which is approximately every ~49 days. +//#define DEPRECATED_WINDOWS_SUPPORT + /** * No settings past this point **/ diff --git a/src/login/login.cpp b/src/login/login.cpp index 2883b273cb..1b9c6a9e61 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -215,8 +215,8 @@ static TIMER_FUNC(login_online_data_cleanup){ */ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip) { static int num_regs = 0; // registration counter - static unsigned int new_reg_tick = 0; - unsigned int tick = gettick(); + static t_tick new_reg_tick = 0; + t_tick tick = gettick(); struct mmo_account acc; //Account Registration Flood Protection by [Kevin] diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 4bdb46c213..21ddf70495 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4681,7 +4681,7 @@ ACMD_FUNC(reloadnpcfile) { /*========================================== * time in txt for time command (by [Yor]) *------------------------------------------*/ -char* txt_time(unsigned int duration) +char* txt_time(t_tick duration_) { int days, hours, minutes, seconds; char temp[CHAT_SIZE_MAX]; @@ -4690,6 +4690,9 @@ char* txt_time(unsigned int duration) memset(temp, '\0', sizeof(temp)); memset(temp1, '\0', sizeof(temp1)); + // Cap it + int duration = (int)duration_; + days = duration / (60 * 60 * 24); duration = duration - (60 * 60 * 24 * days); hours = duration / (60 * 60); @@ -5760,7 +5763,7 @@ ACMD_FUNC(useskill) ACMD_FUNC(displayskill) { struct status_data * status; - unsigned int tick; + t_tick tick; uint16 skill_id; uint16 skill_lv = 1; nullpo_retr(-1, sd); @@ -6779,7 +6782,7 @@ ACMD_FUNC(summon) int mob_id = 0; int duration = 0; struct mob_data *md; - unsigned int tick=gettick(); + t_tick tick=gettick(); nullpo_retr(-1, sd); diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 41a6e6b374..d9db6ebd58 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -264,7 +264,7 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int * @param isspdamage: If the damage is done to SP * @param tick: Current tick *------------------------------------------*/ -void battle_damage(struct block_list *src, struct block_list *target, int64 damage, int delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, unsigned int tick, bool isspdamage) { +void battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool isspdamage) { map_freeblock_lock(); if (isspdamage) status_fix_spdamage(src, target, damage, delay); @@ -288,7 +288,7 @@ struct delay_damage { int src_id; int target_id; int64 damage; - int delay; + t_tick delay; unsigned short distance; uint16 skill_lv; uint16 skill_id; @@ -339,7 +339,7 @@ TIMER_FUNC(battle_delay_damage_sub){ return 0; } -int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects, bool isspdamage) +int battle_delay_damage(t_tick tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, t_tick ddelay, bool additional_effects, bool isspdamage) { struct delay_damage *dat; struct status_change *sc; @@ -5026,7 +5026,7 @@ static void battle_calc_attack_gvg_bg(struct Damage* wd, struct block_list *src, int64 damage = wd->damage + wd->damage2, rdamage = 0; struct map_session_data *tsd = BL_CAST(BL_PC, target); struct status_data *sstatus = status_get_status_data(src); - int tick = gettick(), rdelay = 0; + t_tick tick = gettick(), rdelay = 0; rdamage = battle_calc_return_damage(target, src, &damage, wd->flag, skill_id, false); if( rdamage > 0 ) { //Item reflect gets calculated before any mapflag reducing is applicated @@ -5293,7 +5293,7 @@ void battle_do_reflect(int attack_type, struct Damage *wd, struct block_list* sr struct status_change *tsc = status_get_sc(target); struct status_data *sstatus = status_get_status_data(src); struct unit_data *ud = unit_bl2ud(target); - int tick = gettick(), rdelay = 0; + t_tick tick = gettick(), rdelay = 0; if (!tsc) return; @@ -7086,7 +7086,7 @@ void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rda * Original coder pakpil */ int battle_damage_area(struct block_list *bl, va_list ap) { - unsigned int tick; + t_tick tick; int64 damage; int amotion, dmotion; struct block_list *src; @@ -7119,7 +7119,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) { /*========================================== * Do a basic physical attack (call through unit_attack_timer) *------------------------------------------*/ -enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag) { +enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, t_tick tick, int flag) { struct map_session_data *sd = NULL, *tsd = NULL; struct status_data *sstatus, *tstatus; struct status_change *sc, *tsc; diff --git a/src/map/battle.hpp b/src/map/battle.hpp index d807b2f03b..eb75174330 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -102,13 +102,13 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag); int64 battle_calc_bg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag); -void battle_damage(struct block_list *src, struct block_list *target, int64 damage, int delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, unsigned int tick, bool spdamage); -int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects, bool spdamage); +void battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool spdamage); +int battle_delay_damage (t_tick tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, t_tick ddelay, bool additional_effects, bool spdamage); int battle_calc_chorusbonus(struct map_session_data *sd); // Summary normal attack treatment (basic attack) -enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,unsigned int tick,int flag); +enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,t_tick tick,int flag); // Accessors struct block_list* battle_get_master(struct block_list *src); diff --git a/src/map/channel.cpp b/src/map/channel.cpp index 579dc19b21..fee78b6b57 100644 --- a/src/map/channel.cpp +++ b/src/map/channel.cpp @@ -219,7 +219,7 @@ int channel_join(struct Channel *channel, struct map_session_data *sd) { RECREATE(sd->channels, struct Channel *, ++sd->channel_count); sd->channels[ sd->channel_count - 1 ] = channel; idb_put(channel->users, sd->status.char_id, sd); - RECREATE(sd->channel_tick, unsigned int, sd->channel_count); + RECREATE(sd->channel_tick, t_tick, sd->channel_count); sd->channel_tick[sd->channel_count-1] = 0; if( sd->stealth ) { diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index c51d6f4e05..6d61064b01 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -1305,7 +1305,7 @@ int chrif_updatefamelist_ack(int fd) { int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex] #ifdef ENABLE_SC_SAVING int i, count=0; - unsigned int tick; + t_tick tick; struct status_change_data data; struct status_change *sc = &sd->sc; const struct TimerData *timer; @@ -1351,7 +1351,7 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the int chrif_skillcooldown_save(struct map_session_data *sd) { int i, count = 0; struct skill_cooldown_data data; - unsigned int tick; + t_tick tick; const struct TimerData *timer; chrif_check(-1); @@ -1681,7 +1681,7 @@ int chrif_bsdata_save(struct map_session_data *sd, bool quit) { WFIFOL(char_fd, 4) = sd->status.char_id; if (sd->bonus_script.count) { - unsigned int tick = gettick(); + t_tick tick = gettick(); struct linkdb_node *node = NULL; for (node = sd->bonus_script.head; node && i < MAX_PC_BONUS_SCRIPT; node = node->next) { diff --git a/src/map/chrif.hpp b/src/map/chrif.hpp index 7c625f8c80..c76724b789 100644 --- a/src/map/chrif.hpp +++ b/src/map/chrif.hpp @@ -7,6 +7,7 @@ #include #include "../common/cbasetypes.hpp" +#include "../common/timer.hpp" // t_tick #include "../common/socket.hpp" // enum chrif_req_op //fwd declaration @@ -30,7 +31,7 @@ struct auth_node { time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) struct map_session_data *sd; //Data from logged on char. struct mmo_charstatus *char_dat; //Data from char server. - unsigned int node_created; //timestamp for node timeouts + t_tick node_created; //timestamp for node timeouts enum sd_state state; //To track whether player was login in/out or changing maps. }; diff --git a/src/map/clif.cpp b/src/map/clif.cpp index ca47f472c1..f4e13e879c 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -57,6 +57,10 @@ #include "unit.hpp" #include "vending.hpp" +static inline uint32 client_tick( t_tick tick ){ + return (uint32)tick; +} + /* for clif_clearunit_delayed */ static struct eri *delay_clearunit_ers; @@ -667,7 +671,7 @@ void clif_authok(struct map_session_data *sd) WFIFOHEAD(fd,packet_len(cmd)); WFIFOW(fd, 0) = cmd; - WFIFOL(fd, 2) = gettick(); + WFIFOL(fd, 2) = client_tick(gettick()); WFIFOPOS(fd, 6, sd->bl.x, sd->bl.y, sd->ud.dir); WFIFOB(fd, 9) = 5; // ignored WFIFOB(fd,10) = 5; // ignored @@ -895,7 +899,7 @@ static TIMER_FUNC(clif_clearunit_delayed_sub){ ers_free(delay_clearunit_ers,bl); return 0; } -void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int tick) +void clif_clearunit_delayed(struct block_list* bl, clr_type type, t_tick tick) { struct block_list *tbl = ers_alloc(delay_clearunit_ers, struct block_list); memcpy (tbl, bl, sizeof (struct block_list)); @@ -1246,12 +1250,12 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un WBUFW(buf,18) = vd->weapon; #if PACKETVER < 4 WBUFW(buf,20) = vd->head_bottom; - WBUFL(buf,22) = gettick(); + WBUFL(buf,22) = client_tick(gettick()); WBUFW(buf,26) = vd->shield; #else WBUFW(buf,20) = vd->shield; WBUFW(buf,22) = vd->head_bottom; - WBUFL(buf,24) = gettick(); + WBUFL(buf,24) = client_tick(gettick()); #endif WBUFW(buf,28) = vd->head_top; WBUFW(buf,30) = vd->head_mid; @@ -1707,7 +1711,7 @@ void clif_walkok(struct map_session_data *sd) WFIFOHEAD(fd, packet_len(0x87)); WFIFOW(fd,0)=0x87; - WFIFOL(fd,2)=gettick(); + WFIFOL(fd,2)=client_tick(gettick()); WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y,8,8); WFIFOSET(fd,packet_len(0x87)); } @@ -1783,7 +1787,7 @@ void clif_move(struct unit_data *ud) WBUFW(buf,0)=0x86; WBUFL(buf,2)=-bl->id; WBUFPOS2(buf,6,bl->x,bl->y,ud->to_x,ud->to_y,8,8); - WBUFL(buf,12)=gettick(); + WBUFL(buf,12)=client_tick(gettick()); clif_send(buf, packet_len(0x86), bl, SELF); } return; @@ -1809,7 +1813,7 @@ void clif_move(struct unit_data *ud) WBUFW(buf,0)=0x86; WBUFL(buf,2)=bl->id; WBUFPOS2(buf,6,bl->x,bl->y,ud->to_x,ud->to_y,8,8); - WBUFL(buf,12)=gettick(); + WBUFL(buf,12)=client_tick(gettick()); clif_send(buf, packet_len(0x86), bl, AREA_WOS); if (disguised(bl)) { WBUFL(buf,2)=-bl->id; @@ -4777,7 +4781,7 @@ static int clif_hallucination_damage() /// 10 = critical hit /// 11 = lucky dodge /// 12 = (touch skill?) -int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 sdamage, int div, enum e_damage_type type, int64 sdamage2, bool spdamage) +int clif_damage(struct block_list* src, struct block_list* dst, t_tick tick, int sdelay, int ddelay, int64 sdamage, int div, enum e_damage_type type, int64 sdamage2, bool spdamage) { unsigned char buf[34]; struct status_change *sc; @@ -4809,7 +4813,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic WBUFW(buf,0) = cmd; WBUFL(buf,2) = src->id; WBUFL(buf,6) = dst->id; - WBUFL(buf,10) = tick; + WBUFL(buf,10) = client_tick(tick); WBUFL(buf,14) = sdelay; WBUFL(buf,18) = ddelay; if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) { @@ -5515,7 +5519,7 @@ void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_f /// Skill cooldown display icon (ZC_SKILL_POSTDELAY). /// 043d .W .L -void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int tick) +void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, t_tick tick) { #if PACKETVER>=20081112 int fd; @@ -5526,7 +5530,7 @@ void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned WFIFOHEAD(fd,packet_len(0x43d)); WFIFOW(fd,0) = 0x43d; WFIFOW(fd,2) = skill_id; - WFIFOL(fd,4) = tick; + WFIFOL(fd,4) = client_tick(tick); WFIFOSET(fd,packet_len(0x43d)); #endif } @@ -5534,7 +5538,7 @@ void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned /// Skill attack effect and damage. /// 0114 .W .L .L .L .L .L .W .W
.W .B (ZC_NOTIFY_SKILL) /// 01de .W .L .L .L .L .L .L .W
.W .B (ZC_NOTIFY_SKILL2) -int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int64 sdamage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type) +int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int64 sdamage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type) { unsigned char buf[64]; struct status_change *sc; @@ -5555,7 +5559,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int WBUFW(buf,2)=skill_id; WBUFL(buf,4)=src->id; WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; + WBUFL(buf,12)=client_tick(tick); WBUFL(buf,16)=sdelay; WBUFL(buf,20)=ddelay; if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) { @@ -5586,7 +5590,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int WBUFW(buf,2)=skill_id; WBUFL(buf,4)=src->id; WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; + WBUFL(buf,12)=client_tick(tick); WBUFL(buf,16)=sdelay; WBUFL(buf,20)=ddelay; if (battle_config.hide_woe_damage && map_flag_gvg(src->m)) { @@ -5630,7 +5634,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int /// Ground skill attack effect and damage (ZC_NOTIFY_SKILL_POSITION). /// 0115 .W .L .L .L .L .L .W .W .W .W
.W .B /* -int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type) +int clif_skill_damage2(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type) { unsigned char buf[64]; struct status_change *sc; @@ -5651,7 +5655,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in WBUFW(buf,2)=skill_id; WBUFL(buf,4)=src->id; WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; + WBUFL(buf,12)=client_tick(tick); WBUFL(buf,16)=sdelay; WBUFL(buf,20)=ddelay; WBUFW(buf,24)=dst->x; @@ -5689,7 +5693,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in /// Non-damaging skill effect /// 011a .W .W .L .L .B (ZC_USE_SKILL). /// 09cb .W .L .L .L .B (ZC_USE_SKILL2). -int clif_skill_nodamage(struct block_list *src,struct block_list *dst, uint16 skill_id, int heal, int fail) +bool clif_skill_nodamage(struct block_list *src,struct block_list *dst, uint16 skill_id, int heal, t_tick tick) { unsigned char buf[17]; #if PACKETVER < 20130731 @@ -5698,6 +5702,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst, uint16 sk const int cmd = 0x9cb; #endif int offset = 0; + bool success = ( tick != 0 ); nullpo_ret(dst); @@ -5711,7 +5716,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst, uint16 sk #endif WBUFL(buf,6+offset) = dst->id; WBUFL(buf,10+offset) = src ? src->id : 0; - WBUFB(buf,14+offset) = fail; + WBUFB(buf,14+offset) = success; if (disguised(dst)) { clif_send(buf, packet_len(cmd), dst, AREA_WOS); @@ -5727,13 +5732,13 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst, uint16 sk clif_send(buf, packet_len(cmd), src, SELF); } - return fail; + return success; } /// Non-damaging ground skill effect (ZC_NOTIFY_GROUNDSKILL). /// 0117 .W .L .W .W .W .L -void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,int y,int tick) +void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,int y,t_tick tick) { unsigned char buf[32]; @@ -5745,7 +5750,7 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i WBUFW(buf,8)=val; WBUFW(buf,10)=x; WBUFW(buf,12)=y; - WBUFL(buf,14)=tick; + WBUFL(buf,14)=client_tick(tick); if(disguised(src)) { clif_send(buf,packet_len(0x117),src,AREA_WOS); WBUFL(buf,4)=-src->id; @@ -5975,7 +5980,7 @@ void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 skill_id /// @param val1 /// @param val2 /// @param val3 -void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, int tick, int val1, int val2, int val3, enum send_target target_type) +void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, t_tick tick, int val1, int val2, int val3, enum send_target target_type) { unsigned char buf[32]; @@ -6005,8 +6010,8 @@ void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, i if (tick <= 0) tick = 9999; // this is indeed what official servers do - WBUFL(buf,9) = tick;/* at this stage remain and total are the same value I believe */ - WBUFL(buf,13) = tick; + WBUFL(buf,9) = client_tick(tick);/* at this stage remain and total are the same value I believe */ + WBUFL(buf,13) = client_tick(tick); WBUFL(buf,17) = val1; WBUFL(buf,21) = val2; WBUFL(buf,25) = val3; @@ -6016,7 +6021,7 @@ void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, i if (tick <= 0) tick = 9999; // this is indeed what official servers do - WBUFL(buf,9) = tick; + WBUFL(buf,9) = client_tick(tick); WBUFL(buf,13) = val1; WBUFL(buf,17) = val2; WBUFL(buf,21) = val3; @@ -6034,7 +6039,7 @@ void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, i * @param val2 * @param val3 */ -void clif_status_change(struct block_list *bl, int type, int flag, int tick, int val1, int val2, int val3) { +void clif_status_change(struct block_list *bl, int type, int flag, t_tick tick, int val1, int val2, int val3) { struct map_session_data *sd = NULL; if (type == EFST_BLANK) //It shows nothing on the client... @@ -6095,7 +6100,7 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum sc_type type = sc_display[i]->type; struct status_change *sc = status_get_sc(bl); const struct TimerData *td = (sc && sc->data[type] ? get_timer(sc->data[type]->timer) : NULL); - int tick = 0; + t_tick tick = 0; if (td) tick = DIFF_TICK(td->tick, gettick()); @@ -6119,7 +6124,7 @@ void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, /// Notifies the client when a player enters the screen with an active EFST. /// 08ff .L .W .L { .L }*3 (ZC_EFST_SET_ENTER) (PACKETVER >= 20111108) /// 0984 .L .W .L .L { .L }*3 (ZC_EFST_SET_ENTER2) (PACKETVER >= 20120618) -void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, int tick, int val1, int val2, int val3) { +void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, t_tick tick, int val1, int val2, int val3) { #if PACKETVER >= 20111108 unsigned char buf[32]; #if PACKETVER >= 20120618 @@ -6141,9 +6146,9 @@ void clif_efst_status_change(struct block_list *bl, int tid, enum send_target ta WBUFL(buf,offset + 2) = tid; WBUFW(buf,offset + 6) = type; #if PACKETVER >= 20111108 - WBUFL(buf,offset + 8) = tick; // Set remaining status duration [exneval] + WBUFL(buf,offset + 8) = client_tick(tick); // Set remaining status duration [exneval] #if PACKETVER >= 20120618 - WBUFL(buf,offset + 12) = tick; + WBUFL(buf,offset + 12) = client_tick(tick); offset += 4; #endif WBUFL(buf,offset + 12) = val1; @@ -8118,7 +8123,7 @@ void clif_spiritball(struct block_list *bl) { /// Notifies clients in area of a character's combo delay (ZC_COMBODELAY). /// 01d2 .L .L -void clif_combo_delay(struct block_list *bl,int wait) +void clif_combo_delay(struct block_list *bl,t_tick wait) { unsigned char buf[32]; @@ -8126,7 +8131,7 @@ void clif_combo_delay(struct block_list *bl,int wait) WBUFW(buf,0)=0x1d2; WBUFL(buf,2)=bl->id; - WBUFL(buf,6)=wait; + WBUFL(buf,6)=client_tick(wait); clif_send(buf,packet_len(0x1d2),bl,AREA); } @@ -10190,7 +10195,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) struct block_list* bl; struct auth_node* node; int cmd, account_id, char_id, login_id1, sex, err; - unsigned int client_tick; //The client tick is a tick, therefore it needs be unsigned. [Skotlex] + t_tick client_tick; //The client tick is a tick, therefore it needs be unsigned. [Skotlex] if (sd) { ShowError("clif_parse_WantToConnection : invalid request (character already logged in)\n"); @@ -10678,13 +10683,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) /// Server's tick (ZC_NOTIFY_TIME). /// 007f