소스 검색

Move and clean few more thing around

Testing refact, looking good for now.
lighta 11 년 전
부모
커밋
06286ebe7c
8개의 변경된 파일129개의 추가작업 그리고 559개의 파일을 삭제
  1. 2 549
      src/char/char.c
  2. 60 7
      src/char/char_clif.c
  3. 1 0
      src/char/char_clif.h
  4. 24 2
      src/char/char_cnslif.c
  5. 38 1
      src/char/char_logif.c
  6. 1 0
      src/char/char_logif.h
  7. 2 0
      src/char/char_mapif.c
  8. 1 0
      src/common/cli.h

+ 2 - 549
src/char/char.c

@@ -75,25 +75,7 @@ struct s_subnet {
 } subnet[16];
 int subnet_count = 0;
 
-int mapif_vipack(int mapfd, uint32 aid, uint32 vip_time, uint8 isvip, uint8 isgm, uint32 groupid);
-int loginif_reqvipdata(uint32 aid, uint8 type, int add_vip_time, int mapfd);
-int loginif_parse_vipack(int fd);
-
-// Addon system
-void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason );
-
-int loginif_BankingReq(int32 account_id, int8 type, int32 data);
-int loginif_parse_BankingAck(int fd);
-int mapif_BankingAck(int32 account_id, int32 bank_vault);
-
-
-//Bonus Script
-void bonus_script_get(int fd);///Get bonus_script data
-void bonus_script_save(int fd); ///Save bonus_script data
-
-
 int char_chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
-int delete_char_sql(int char_id);
 
 DBMap* auth_db; // int account_id -> struct auth_node*
 DBMap* online_char_db; // int account_id -> struct online_char_data*
@@ -1753,158 +1735,6 @@ int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 }
 
 
-
-//----------------------------------------
-// Tell client how many pages, kRO sends 17 (Yommy)
-//----------------------------------------
-void char_charlist_notify( int fd, struct char_session_data* sd ){
-	int found=0, count=0, i=0;
-	for(i=0; i<MAX_CHARS; i++){
-		if(sd->found_char[i] != -1){
-			found=1;
-		}
-		if(i%3 && found){ //each page contains 3char max
-			count++;
-			found=0;
-		}
-	}
-
-	WFIFOHEAD(fd, 6);
-	WFIFOW(fd, 0) = 0x9a0;
-	// pages to req / send them all in 1 until mmo_chars_fromsql can split them up
-	WFIFOL(fd, 2) = count?count:1;
-	WFIFOSET(fd,6);
-}
-
-void char_block_character( int fd, struct char_session_data* sd );
-int charblock_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
-	struct char_session_data* sd=NULL;
-	int i=0;
-	ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == id);
-
-	if(sd == NULL || sd->charblock_timer==INVALID_TIMER) //has disconected or was required to stop
-		return 0;
-	if (sd->charblock_timer != tid){
-		sd->charblock_timer = INVALID_TIMER;
-		return 0;
-	}
-	char_block_character(i,sd);
-	return 0;
-}
-/*
- * 0x20d <PacketLength>.W <TAG_CHARACTER_BLOCK_INFO>24B (HC_BLOCK_CHARACTER)
- * <GID>L <szExpireDate>20B (TAG_CHARACTER_BLOCK_INFO)
- */
-void char_block_character( int fd, struct char_session_data* sd){
-	int i=0, j=0, len=4;
-	time_t now = time(NULL);
-
-	WFIFOHEAD(fd, 4+MAX_CHARS*24);
-	WFIFOW(fd, 0) = 0x20d;
-
-	for(i=0; i<MAX_CHARS; i++){
-		if(sd->found_char[i] == -1)
-			continue;
-		if(sd->unban_time[i]){
-			if( sd->unban_time[i] > now ) {
-				char szExpireDate[21];
-				WFIFOL(fd, 4+j*24) = sd->found_char[i];
-				timestamp2string(szExpireDate, 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S");
-				memcpy(WFIFOP(fd,8+j*24),szExpireDate,20);
-			}
-			else {
-				WFIFOL(fd, 4+j*24) = 0;
-				sd->unban_time[i] = 0;
-				if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, sd->found_char[i]) )
-					Sql_ShowDebug(sql_handle);
-			}
-			len+=24;
-			j++; //pkt list idx
-		}
-	}
-	WFIFOW(fd, 2) = len; //packet len
-	WFIFOSET(fd,len);
-
-	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //sd->charslot only have productible char
-	if(i < MAX_CHARS ){
-		sd->charblock_timer = add_timer(
-			gettick() + 10000,	// each 10s resend that list
-			charblock_timer, sd->account_id, 0);
-	}
-}
-
-void mmo_char_send099d(int fd, struct char_session_data *sd) {
-	WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF));
-	WFIFOW(fd,0) = 0x99d;
-	WFIFOW(fd,2) = char_mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4;
-	WFIFOSET(fd,WFIFOW(fd,2));
-}
-
-
-//----------------------------------------
-// Function to send characters to a player
-//----------------------------------------
-int mmo_char_send006b(int fd, struct char_session_data* sd){
-	int j, offset = 0;
-	bool newvers = (sd->version >= date2version(20100413));
-	if(newvers) //20100413
-		offset += 3;
-	if ( charserv_config.save_log )
-		ShowInfo("Loading Char Data 6b ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
-
-	j = 24 + offset; // offset
-	WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
-	WFIFOW(fd,0) = 0x6b;
-	if(newvers){ //20100413
-		WFIFOB(fd,4) = MAX_CHARS; // Max slots
-		WFIFOB(fd,5) = MAX_CHARS - sd->chars_billing - sd->chars_vip; // PremiumStartSlot
-		WFIFOB(fd,6) = MAX_CHARS - sd->chars_billing; // PremiumEndSlot
-		/* this+0x7  char dummy1_beginbilling */
-		/* this+0x8  unsigned long code */
-		/* this+0xc  unsigned long time1 */
-		/* this+0x10  unsigned long time2 */
-		/* this+0x14  char dummy2_endbilling[7] */
-	}
-	memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes 4-24 7-27
-	j+=char_mmo_chars_fromsql(sd, WFIFOP(fd,j));
-	WFIFOW(fd,2) = j; // packet len
-	WFIFOSET(fd,j);
-
-	return 0;
-}
-
-//----------------------------------------
-// Notify client about charselect window data [Ind]
-//----------------------------------------
-void mmo_char_send082d(int fd, struct char_session_data* sd) {
-	if (charserv_config.save_log)
-		ShowInfo("Loading Char Data 82d ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
-	WFIFOHEAD(fd,29);
-	WFIFOW(fd,0) = 0x82d;
-	WFIFOW(fd,2) = 29;
-	WFIFOB(fd,4) = MAX_CHARS - sd->chars_billing - sd->chars_vip; //NormalSlotNum
-	WFIFOB(fd,5) = sd->chars_vip; //PremiumSlotNum
-	WFIFOB(fd,6) = sd->chars_billing; //BillingSlotNum
-	WFIFOB(fd,7) = sd->char_slots; //ProducibleSlotNum
-	WFIFOB(fd,8) = sd->char_slots; //ValidSlotNum
-	memset(WFIFOP(fd,9), 0, 20); // unused bytes
-	WFIFOSET(fd,29);
-}
-
-void mmo_char_send(int fd, struct char_session_data* sd){
-	//ShowInfo("sd->version = %d\n",sd->version);
-	if(sd->version > date2version(20130000) ){
-		mmo_char_send082d(fd,sd);
-		char_charlist_notify(fd,sd);
-	}
-	//else
-	//@FIXME dump from kro doesn't show 6b transmission
-	mmo_char_send006b(fd,sd);
-	if(sd->version > date2version(20060819) )
-		char_block_character(fd,sd);
-}
-
 int char_married(int pl1, int pl2)
 {
 	if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `partner_id` FROM `%s` WHERE `char_id` = '%d'", schema_config.char_db, pl1) )
@@ -2018,106 +1848,6 @@ void char_auth_ok(int fd, struct char_session_data *sd) {
 	// continues when account data is received...
 }
 
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
-void mapif_server_reset(int id);
-
-
-
-/// Resets all the data.
-void loginif_reset(void)
-{
-	int id;
-	// TODO kick everyone out and reset everything or wait for connect and try to reaquire locks [FlavioJS]
-	for( id = 0; id < ARRAYLENGTH(map_server); ++id )
-		mapif_server_reset(id);
-	flush_fifos();
-	exit(EXIT_FAILURE);
-}
-
-
-/// Checks the conditions for the server to stop.
-/// Releases the cookie when all characters are saved.
-/// If all the conditions are met, it stops the core loop.
-void loginif_check_shutdown(void)
-{
-	if( runflag != CHARSERVER_ST_SHUTDOWN )
-		return;
-	runflag = CORE_ST_STOP;
-}
-
-
-/// Called when the connection to Login Server is disconnected.
-void loginif_on_disconnect(void)
-{
-	ShowWarning("Connection to Login Server lost.\n\n");
-}
-
-
-/// Called when all the connection steps are completed.
-void loginif_on_ready(void)
-{
-	int i;
-
-	loginif_check_shutdown();
-
-	//Send online accounts to login server.
-	send_accounts_tologin(INVALID_TIMER, gettick(), 0, 0);
-
-	// if no map-server already connected, display a message...
-	ARR_FIND( 0, ARRAYLENGTH(map_server), i, map_server[i].fd > 0 && map_server[i].map[0] );
-	if( i == ARRAYLENGTH(map_server) )
-		ShowStatus("Awaiting maps from map-server.\n");
-}
-
-
-int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data);
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
-
-void do_init_loginif(void)
-{
-	// establish char-login connection if not present
-	add_timer_func_list(check_connect_login_server, "check_connect_login_server");
-	add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000);
-
-	// send a list of all online account IDs to login server
-	add_timer_func_list(send_accounts_tologin, "send_accounts_tologin");
-	add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour
-}
-
-void do_final_loginif(void)
-{
-	if( login_fd != -1 )
-	{
-		do_close(login_fd);
-		login_fd = -1;
-	}
-}
-
-int char_request_accreg2(int account_id, int char_id)
-{
-	loginif_check(0);
-
-	WFIFOHEAD(login_fd,10);
-	WFIFOW(login_fd,0) = 0x272e;
-	WFIFOL(login_fd,2) = account_id;
-	WFIFOL(login_fd,6) = char_id;
-	WFIFOSET(login_fd,10);
-	return 1;
-}
-
-//Send packet forward to login-server for account saving
-int char_save_accreg2(unsigned char* buf, int len)
-{
-	loginif_check(0);
-
-	WFIFOHEAD(login_fd,len+4);
-	memcpy(WFIFOP(login_fd,4), buf, len);
-	WFIFOW(login_fd,0) = 0x2728;
-	WFIFOW(login_fd,2) = len+4;
-	WFIFOSET(login_fd,len+4);
-	return 1;
-}
-
 void char_read_fame_list(void)
 {
 	int i;
@@ -2176,43 +1906,6 @@ void char_read_fame_list(void)
 	Sql_FreeResult(sql_handle);
 }
 
-// Send map-servers the fame ranking lists
-int char_send_fame_list(int fd)
-{
-	int i, len = 8;
-	unsigned char buf[32000];
-
-	WBUFW(buf,0) = 0x2b1b;
-
-	for(i = 0; i < fame_list_size_smith && smith_fame_list[i].id; i++) {
-		memcpy(WBUFP(buf, len), &smith_fame_list[i], sizeof(struct fame_list));
-		len += sizeof(struct fame_list);
-	}
-	// add blacksmith's block length
-	WBUFW(buf, 6) = len;
-
-	for(i = 0; i < fame_list_size_chemist && chemist_fame_list[i].id; i++) {
-		memcpy(WBUFP(buf, len), &chemist_fame_list[i], sizeof(struct fame_list));
-		len += sizeof(struct fame_list);
-	}
-	// add alchemist's block length
-	WBUFW(buf, 4) = len;
-
-	for(i = 0; i < fame_list_size_taekwon && taekwon_fame_list[i].id; i++) {
-		memcpy(WBUFP(buf, len), &taekwon_fame_list[i], sizeof(struct fame_list));
-		len += sizeof(struct fame_list);
-	}
-	// add total packet length
-	WBUFW(buf, 2) = len;
-
-	if (fd != -1)
-		chmapif_send(fd, buf, len);
-	else
-		chmapif_sendall(buf, len);
-
-	return 0;
-}
-
 //Loads a character's name and stores it in the buffer given (must be NAME_LENGTH in size)
 //Returns 1 on found, 0 on not found (buffer is filled with Unknown char name)
 int char_loadName(int char_id, char* name){
@@ -2234,77 +1927,6 @@ int char_loadName(int char_id, char* name){
 	return 0;
 }
 
-int search_mapserver(unsigned short map, uint32 ip, uint16 port);
-
-
-/// Initializes a server structure.
-void mapif_server_init(int id)
-{
-	memset(&map_server[id], 0, sizeof(map_server[id]));
-	map_server[id].fd = -1;
-}
-
-
-/// Destroys a server structure.
-void mapif_server_destroy(int id)
-{
-	if( map_server[id].fd == -1 )
-	{
-		do_close(map_server[id].fd);
-		map_server[id].fd = -1;
-	}
-}
-
-
-/// Resets all the data related to a server.
-void mapif_server_reset(int id)
-{
-	int i,j;
-	unsigned char buf[16384];
-	int fd = map_server[id].fd;
-	//Notify other map servers that this one is gone. [Skotlex]
-	WBUFW(buf,0) = 0x2b20;
-	WBUFL(buf,4) = htonl(map_server[id].ip);
-	WBUFW(buf,8) = htons(map_server[id].port);
-	j = 0;
-	for(i = 0; i < MAX_MAP_PER_SERVER; i++)
-		if (map_server[id].map[i])
-			WBUFW(buf,10+(j++)*4) = map_server[id].map[i];
-	if (j > 0) {
-		WBUFW(buf,2) = j * 4 + 10;
-		chmapif_sendallwos(fd, buf, WBUFW(buf,2));
-	}
-	if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `index`='%d'", schema_config.ragsrvinfo_db, map_server[id].fd) )
-		Sql_ShowDebug(sql_handle);
-	online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
-	mapif_server_destroy(id);
-	mapif_server_init(id);
-}
-
-
-/// Called when the connection to a Map Server is disconnected.
-void mapif_on_disconnect(int id)
-{
-	ShowStatus("Map-server #%d has disconnected.\n", id);
-	mapif_server_reset(id);
-}
-
-
-
-void do_init_mapif(void)
-{
-	int i;
-	for( i = 0; i < ARRAYLENGTH(map_server); ++i )
-		mapif_server_init(i);
-}
-
-void do_final_mapif(void)
-{
-	int i;
-	for( i = 0; i < ARRAYLENGTH(map_server); ++i )
-		mapif_server_destroy(i);
-}
-
 // Searches for the mapserver that has a given map (and optionally ip/port, if not -1).
 // If found, returns the server's index in the 'server' array (otherwise returns -1).
 int char_search_mapserver(unsigned short map, uint32 ip, uint16 port){
@@ -2342,70 +1964,6 @@ int char_lan_subnetcheck(uint32 ip){
 	}
 }
 
-
-/// @param result
-/// 0 (0x718): An unknown error has occurred.
-/// 1: none/success
-/// 3 (0x719): A database error occurred.
-/// 4 (0x71a): To delete a character you must withdraw from the guild.
-/// 5 (0x71b): To delete a character you must withdraw from the party.
-/// Any (0x718): An unknown error has occurred.
-void char_delete2_ack(int fd, int char_id, uint32 result, time_t delete_date)
-{// HC: <0828>.W <char id>.L <Msg:0-5>.L <deleteDate>.L
-	WFIFOHEAD(fd,14);
-	WFIFOW(fd,0) = 0x828;
-	WFIFOL(fd,2) = char_id;
-	WFIFOL(fd,6) = result;
-#if PACKETVER > 20130000
-	WFIFOL(fd,10) = TOL(delete_date - time(NULL));
-#else
-	WFIFOL(fd,10) = TOL(delete_date);
-#endif
-	WFIFOSET(fd,14);
-}
-
-
-/// @param result
-/// 0 (0x718): An unknown error has occurred.
-/// 1: none/success
-/// 2 (0x71c): Due to system settings can not be deleted.
-/// 3 (0x719): A database error occurred.
-/// 4 (0x71d): Deleting not yet possible time.
-/// 5 (0x71e): Date of birth do not match.
-/// Any (0x718): An unknown error has occurred.
-void char_delete2_accept_ack(int fd, int char_id, uint32 result)
-{// HC: <082a>.W <char id>.L <Msg:0-5>.L
-	if(result == 1 ){
-		struct char_session_data* sd;
-		sd = (struct char_session_data*)session[fd]->session_data;
-
-		if( sd->version >= date2version(20130000) ){
-			mmo_char_send(fd, sd);
-		}
-	}
-	
-	WFIFOHEAD(fd,10);
-	WFIFOW(fd,0) = 0x82a;
-	WFIFOL(fd,2) = char_id;
-	WFIFOL(fd,6) = result;
-	WFIFOSET(fd,10);
-}
-
-
-/// @param result
-/// 1 (0x718): none/success, (if char id not in deletion process): An unknown error has occurred.
-/// 2 (0x719): A database error occurred.
-/// Any (0x718): An unknown error has occurred.
-void char_delete2_cancel_ack(int fd, int char_id, uint32 result)
-{// HC: <082c>.W <char id>.L <Msg:1-2>.L
-	WFIFOHEAD(fd,10);
-	WFIFOW(fd,0) = 0x82c;
-	WFIFOL(fd,2) = char_id;
-	WFIFOL(fd,6) = result;
-	WFIFOSET(fd,10);
-}
-
-
 // Console Command Parser [Wizputer]
 int parse_console(const char* buf)
 {
@@ -2444,111 +2002,6 @@ int parse_console(const char* buf)
 }
 
 
-
-int char_broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
-{
-	uint8 buf[6];
-	int users = char_count_users();
-
-	// only send an update when needed
-	static int prev_users = 0;
-	if( prev_users == users )
-		return 0;
-	prev_users = users;
-
-	if( chlogif_isconnected() )
-	{
-		// send number of user to login server
-		WFIFOHEAD(login_fd,6);
-		WFIFOW(login_fd,0) = 0x2714;
-		WFIFOL(login_fd,2) = users;
-		WFIFOSET(login_fd,6);
-	}
-
-	// send number of players to all map-servers
-	WBUFW(buf,0) = 0x2b00;
-	WBUFL(buf,2) = users;
-	chmapif_sendall(buf,6);
-
-	return 0;
-}
-
-/**
- * Load this character's account id into the 'online accounts' packet
- * @see DBApply
- */
-static int send_accounts_tologin_sub(DBKey key, DBData *data, va_list ap)
-{
-	struct online_char_data* character = db_data2ptr(data);
-	int* i = va_arg(ap, int*);
-
-	if(character->server > -1)
-	{
-		WFIFOL(login_fd,8+(*i)*4) = character->account_id;
-		(*i)++;
-		return 1;
-	}
-	return 0;
-}
-
-/**
- * Timered function to send all account_id connected to login-serv
- * @param tid : Timer id
- * @param tick : Scheduled tick
- * @param id : GID linked to that timered call
- * @param data : data transmited for delayed function
- * @return 
- */
-int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
-{
-	if (chlogif_isconnected())
-	{
-		// send account list to login server
-		int users = online_char_db->size(online_char_db);
-		int i = 0;
-
-		WFIFOHEAD(login_fd,8+users*4);
-		WFIFOW(login_fd,0) = 0x272d;
-		online_char_db->foreach(online_char_db, send_accounts_tologin_sub, &i, users);
-		WFIFOW(login_fd,2) = 8+ i*4;
-		WFIFOL(login_fd,4) = i;
-		WFIFOSET(login_fd,WFIFOW(login_fd,2));
-	}
-	return 0;
-}
-
-int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data)
-{
-	if (login_fd > 0 && session[login_fd] != NULL)
-		return 0;
-
-	ShowInfo("Attempt to connect to login-server...\n");
-	login_fd = make_connection(charserv_config.login_ip, charserv_config.login_port, false,10);
-	if (login_fd == -1)
-	{	//Try again later. [Skotlex]
-		login_fd = 0;
-		return 0;
-	}
-	session[login_fd]->func_parse = chlogif_parse;
-	session[login_fd]->flag.server = 1;
-	realloc_fifo(login_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
-
-	WFIFOHEAD(login_fd,86);
-	WFIFOW(login_fd,0) = 0x2710;
-	memcpy(WFIFOP(login_fd,2), charserv_config.userid, 24);
-	memcpy(WFIFOP(login_fd,26), charserv_config.passwd, 24);
-	WFIFOL(login_fd,50) = 0;
-	WFIFOL(login_fd,54) = htonl(charserv_config.char_ip);
-	WFIFOW(login_fd,58) = htons(charserv_config.char_port);
-	memcpy(WFIFOP(login_fd,60), charserv_config.server_name, 20);
-	WFIFOW(login_fd,80) = 0;
-	WFIFOW(login_fd,82) = charserv_config.char_maintenance;
-	WFIFOW(login_fd,84) = charserv_config.char_new_display; //only display (New) if they want to [Kevin]
-	WFIFOSET(login_fd,86);
-
-	return 1;
-}
-
 //------------------------------------------------
 //Pincode system
 //------------------------------------------------
@@ -3426,8 +2879,8 @@ int do_init(int argc, char **argv)
 	do_init_chmapif();
 
 	// periodically update the overall user count on all mapservers + login server
-	add_timer_func_list(char_broadcast_user_count, "broadcast_user_count");
-	add_timer_interval(gettick() + 1000, char_broadcast_user_count, 0, 0, 5 * 1000);
+	add_timer_func_list(chlogif_broadcast_user_count, "broadcast_user_count");
+	add_timer_interval(gettick() + 1000, chlogif_broadcast_user_count, 0, 0, 5 * 1000);
 
 	// Timer to clear (online_char_db)
 	add_timer_func_list(char_chardb_waiting_disconnect, "chardb_waiting_disconnect");

+ 60 - 7
src/char/char_clif.c

@@ -10,6 +10,7 @@
 #include "../common/malloc.h"
 #include "../common/strlib.h"
 #include "../common/utils.h"
+#include "../common/timer.h"
 #include "inter.h"
 #include "char.h"
 #include "char_logif.h"
@@ -227,13 +228,6 @@ void chclif_charlist_notify( int fd, struct char_session_data* sd ){
 	WFIFOSET(fd,6);
 }
 
-void chclif_block_character( int fd, struct char_session_data* sd ){
-	WFIFOHEAD(fd, 4);
-	WFIFOW(fd, 0) = 0x20d;
-	WFIFOW(fd, 2) = 4; //packet len
-	WFIFOSET(fd,4);
-}
-
 //----------------------------------------
 // Function to send characters to a player
 //----------------------------------------
@@ -987,6 +981,65 @@ int chclif_parse_reqrename(int fd, struct char_session_data* sd, int cmd){
     return 1;
 }
 
+
+int charblock_timer(int tid, unsigned int tick, int id, intptr_t data)
+{
+	struct char_session_data* sd=NULL;
+	int i=0;
+	ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == id);
+
+	if(sd == NULL || sd->charblock_timer==INVALID_TIMER) //has disconected or was required to stop
+		return 0;
+	if (sd->charblock_timer != tid){
+		sd->charblock_timer = INVALID_TIMER;
+		return 0;
+	}
+	chclif_block_character(i,sd);
+	return 0;
+}
+
+/*
+ * 0x20d <PacketLength>.W <TAG_CHARACTER_BLOCK_INFO>24B (HC_BLOCK_CHARACTER)
+ * <GID>L <szExpireDate>20B (TAG_CHARACTER_BLOCK_INFO)
+ */
+void chclif_block_character( int fd, struct char_session_data* sd){
+	int i=0, j=0, len=4;
+	time_t now = time(NULL);
+
+	WFIFOHEAD(fd, 4+MAX_CHARS*24);
+	WFIFOW(fd, 0) = 0x20d;
+
+	for(i=0; i<MAX_CHARS; i++){
+		if(sd->found_char[i] == -1)
+			continue;
+		if(sd->unban_time[i]){
+			if( sd->unban_time[i] > now ) {
+				char szExpireDate[21];
+				WFIFOL(fd, 4+j*24) = sd->found_char[i];
+				timestamp2string(szExpireDate, 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S");
+				memcpy(WFIFOP(fd,8+j*24),szExpireDate,20);
+			}
+			else {
+				WFIFOL(fd, 4+j*24) = 0;
+				sd->unban_time[i] = 0;
+				if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, sd->found_char[i]) )
+					Sql_ShowDebug(sql_handle);
+			}
+			len+=24;
+			j++; //pkt list idx
+		}
+	}
+	WFIFOW(fd, 2) = len; //packet len
+	WFIFOSET(fd,len);
+
+	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //sd->charslot only have productible char
+	if(i < MAX_CHARS ){
+		sd->charblock_timer = add_timer(
+			gettick() + 10000,	// each 10s resend that list
+			charblock_timer, sd->account_id, 0);
+	}
+}
+
 // 0x28f <char_id>.L
 int chclif_parse_ackrename(int fd, struct char_session_data* sd){
     // 0: Successful

+ 1 - 0
src/char/char_clif.h

@@ -49,6 +49,7 @@ int chclif_parse_ackrename(int fd, struct char_session_data* sd);
 int chclif_ack_captcha(int fd);
 int chclif_parse_reqcaptcha(int fd);
 int chclif_parse_chkcaptcha(int fd);
+void chclif_block_character( int fd, struct char_session_data* sd);
 
 int chclif_parse(int fd);
 

+ 24 - 2
src/char/char_cnslif.c

@@ -32,6 +32,28 @@ void display_helpscreen(bool do_exit)
 		exit(EXIT_SUCCESS);
 }
 
+/**
+ * Timered function to check if the console has a new event to be read.
+ * @param tid: timer id
+ * @param tick: tick of execution
+ * @param id: user account id
+ * @param data: unused
+ * @return 0
+ */
+int cnslif_console_timer(int tid, unsigned int tick, int id, intptr_t data) {
+	char buf[MAX_CONSOLE_IN]; //max cmd atm is 63+63+63+3+3
+
+	memset(buf,0,MAX_CONSOLE_IN); //clear out buf
+
+	if(cli_hasevent()){
+		if(fgets(buf, MAX_CONSOLE_IN, stdin)==NULL)
+			return -1;
+		else if(strlen(buf)>MIN_CONSOLE_IN)
+			cnslif_parse(buf);
+	}
+	return 0;
+}
+
 // Console Command Parser [Wizputer]
 int cnslif_parse(const char* buf)
 {
@@ -71,7 +93,7 @@ int cnslif_parse(const char* buf)
 
 void do_init_chcnslif(void){
 	if( charserv_config.console ){ //start listening
-		add_timer_func_list(parse_console_timer, "parse_console_timer");
-		add_timer_interval(gettick()+1000, parse_console_timer, 0, 0, 1000); //start in 1s each 1sec
+		add_timer_func_list(cnslif_console_timer, "cnslif_console_timer");
+		add_timer_interval(gettick()+1000, cnslif_console_timer, 0, 0, 1000); //start in 1s each 1sec
 	}
 }

+ 38 - 1
src/char/char_logif.c

@@ -94,8 +94,16 @@ static int chlogif_send_acc_tologin_sub(DBKey key, DBData *data, va_list ap) {
 	return 0;
 }
 
+/**
+ * Timered function to send all account_id connected to login-serv
+ * @param tid : Timer id
+ * @param tick : Scheduled tick
+ * @param id : GID linked to that timered call
+ * @param data : data transmited for delayed function
+ * @return 
+ */
 int chlogif_send_acc_tologin(int tid, unsigned int tick, int id, intptr_t data) {
-	if (login_fd > 0 && session[login_fd]){
+	if ( chlogif_isconnected() ){
 		DBMap*  online_char_db = char_get_onlinedb();
 		// send account list to login server
 		int users = online_char_db->size(online_char_db);
@@ -125,6 +133,35 @@ int chlogif_send_usercount(int users){
 	return 0;
 }
 
+
+int chlogif_broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
+{
+	uint8 buf[6];
+	int users = char_count_users();
+
+	// only send an update when needed
+	static int prev_users = 0;
+	if( prev_users == users )
+		return 0;
+	prev_users = users;
+
+	if( chlogif_isconnected() )
+	{
+		// send number of user to login server
+		WFIFOHEAD(login_fd,6);
+		WFIFOW(login_fd,0) = 0x2714;
+		WFIFOL(login_fd,2) = users;
+		WFIFOSET(login_fd,6);
+	}
+
+	// send number of players to all map-servers
+	WBUFW(buf,0) = 0x2b00;
+	WBUFL(buf,2) = users;
+	chmapif_sendall(buf,6);
+
+	return 0;
+}
+
 //Send packet forward to login-server for account saving
 int chlogif_save_accreg2(unsigned char* buf, int len){
 	if (login_fd > 0) {

+ 1 - 0
src/char/char_logif.h

@@ -18,6 +18,7 @@ int chlogif_pincode_notifyLoginPinError( int account_id );
 int chlogif_pincode_notifyLoginPinUpdate( int account_id, char* pin );
 void chlogif_pincode_start(int fd, struct char_session_data* sd);
 int chlogif_send_acc_tologin(int tid, unsigned int tick, int id, intptr_t data);
+int chlogif_broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data);
 int chlogif_send_usercount(int users);
 int chlogif_save_accreg2(unsigned char* buf, int len);
 int chlogif_request_accreg2(int account_id, int char_id);

+ 2 - 0
src/char/char_mapif.c

@@ -1,3 +1,5 @@
+
+
 /**
  * @file char_mapif.c
  * Module purpose is to handle incoming and outgoing requests with map-server.

+ 1 - 0
src/common/cli.h

@@ -34,6 +34,7 @@ extern "C" {
  extern char* MSG_CONF_NAME_EN; //all
 
 extern void display_helpscreen(bool exit);
+bool cli_hasevent();
 void display_versionscreen(bool do_exit);
 bool opt_has_next_value(const char* option, int i, int argc);
 int cli_get_options(int argc, char ** argv);