diff --git a/conf/char_athena.conf b/conf/char_athena.conf index ff792b6383..0053cf38b1 100644 --- a/conf/char_athena.conf +++ b/conf/char_athena.conf @@ -255,4 +255,10 @@ default_map: prontera default_map_x: 156 default_map_y: 191 +// After how many days should inactive clan members be removed from their clan? +// 0: never remove them +// X: remove clan members if they did not log in for X days +// Default: 14 +clan_remove_inactive_days: 14 + import: conf/import/char_conf.txt diff --git a/sql-files/main.sql b/sql-files/main.sql index e0c8b03aeb..4bf5ea4d31 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -230,6 +230,7 @@ CREATE TABLE IF NOT EXISTS `char` ( `sex` ENUM('M','F','U') NOT NULL default 'U', `hotkey_rowshift` tinyint(3) unsigned NOT NULL default '0', `clan_id` int(11) unsigned NOT NULL default '0', + `last_login` datetime DEFAULT NULL, PRIMARY KEY (`char_id`), UNIQUE KEY `name_key` (`name`), KEY `account_id` (`account_id`), diff --git a/sql-files/upgrades/upgrade_20170509.sql b/sql-files/upgrades/upgrade_20170509.sql new file mode 100644 index 0000000000..2eae517c31 --- /dev/null +++ b/sql-files/upgrades/upgrade_20170509.sql @@ -0,0 +1,2 @@ +ALTER TABLE `char` + ADD COLUMN `last_login` datetime DEFAULT NULL AFTER `clan_id`; diff --git a/src/char/char.c b/src/char/char.c index ed7fc15020..864af03a8d 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -110,7 +110,7 @@ void char_set_char_online(int map_id, uint32 char_id, uint32 account_id) { struct mmo_charstatus *cp; //Update DB - if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, char_id) ) + if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1', `last_login`=NOW() WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, char_id) ) Sql_ShowDebug(sql_handle); //Check to see for online conflicts @@ -2142,7 +2142,18 @@ static int char_online_data_cleanup(int tid, unsigned int tick, int id, intptr_t return 0; } +static int char_clan_member_cleanup( int tid, unsigned int tick, int id, intptr_t data ){ + // Auto removal is disabled + if( charserv_config.clan_remove_inactive_days <= 0 ){ + return 0; + } + if( SQL_ERROR == Sql_Query( sql_handle, "UPDATE `%s` SET `clan_id`='0' WHERE `online`='0' AND `clan_id`<>'0' AND `last_login` IS NOT NULL AND `last_login` <= NOW() - INTERVAL %d DAY", schema_config.char_db, charserv_config.clan_remove_inactive_days ) ){ + Sql_ShowDebug(sql_handle); + } + + return 0; +} //---------------------------------- // Reading Lan Support configuration @@ -2233,7 +2244,7 @@ bool char_checkdb(void){ "`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,`hair_color`,`clothes_color`,`weapon`," "`shield`,`head_top`,`head_mid`,`head_bottom`,`robe`,`last_map`,`last_x`,`last_y`,`save_map`," "`save_x`,`save_y`,`partner_id`,`online`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`," - "`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`" + "`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`" " FROM `%s` LIMIT 1;", schema_config.char_db) ){ Sql_ShowDebug(sql_handle); return false; @@ -2686,6 +2697,8 @@ void char_set_defaults(){ safestrncpy(charserv_config.default_map, "prontera", MAP_NAME_LENGTH); charserv_config.default_map_x = 156; charserv_config.default_map_y = 191; + + charserv_config.clan_remove_inactive_days = 14; } /** @@ -2958,6 +2971,8 @@ bool char_config_read(const char* cfgName, bool normal){ charserv_config.default_map_x = atoi(w2); } else if (strcmpi(w1, "default_map_y") == 0) { charserv_config.default_map_y = atoi(w2); + } else if (strcmpi(w1, "clan_remove_inactive_days") == 0) { + charserv_config.clan_remove_inactive_days = atoi(w2); } else if (strcmpi(w1, "import") == 0) { char_config_read(w2, normal); } @@ -3128,6 +3143,10 @@ int do_init(int argc, char **argv) add_timer_func_list(char_online_data_cleanup, "online_data_cleanup"); add_timer_interval(gettick() + 1000, char_online_data_cleanup, 0, 0, 600 * 1000); + // periodically remove players that have not logged in for a long time from clans + add_timer_func_list(char_clan_member_cleanup, "clan_member_cleanup"); + add_timer_interval(gettick() + 1000, char_clan_member_cleanup, 0, 0, 60 * 60 * 1000); // every 60 minutes + //check db tables if(charserv_config.char_check_db && char_checkdb() == 0){ ShowFatalError("char : A tables is missing in sql-server, please fix it, see (sql-files main.sql for structure) \n"); diff --git a/src/char/char.h b/src/char/char.h index 07e240581d..3c2fcd6f79 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -165,6 +165,8 @@ struct CharServ_Config { char default_map[MAP_NAME_LENGTH]; unsigned short default_map_x; unsigned short default_map_y; + + int clan_remove_inactive_days; }; extern struct CharServ_Config charserv_config; diff --git a/src/map/status.c b/src/map/status.c index 1091793dda..fc551889e8 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -10841,6 +10841,17 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty tick_time = tick; tick = tick_time + max(val4,0); break; + case SC_SWORDCLAN: + case SC_ARCWANDCLAN: + case SC_GOLDENMACECLAN: + case SC_CROSSBOWCLAN: + case SC_JUMPINGCLAN: + case SC_CLAN_INFO: + // If the player still has a clan status, but was removed from his clan + if( sd && sd->status.clan_id == 0 ){ + return 0; + } + break; } // Values that must be set regardless of flag&4 e.g. val_flag [Ind]