Forráskód Böngészése

Fix charban, align to Herc model,
Add a timered function to refresh block data if you still on charselection waiting for unban (prevent deco reco for refresh)
Fix char_charlist_notify (0x9a0) counting page. The previous was quite an ugly estimate.

lighta 11 éve
szülő
commit
4f2c1d4eb3
2 módosított fájl, 69 hozzáadás és 28 törlés
  1. 63 21
      src/char/char.c
  2. 6 7
      src/map/chrif.c

+ 63 - 21
src/char/char.c

@@ -149,6 +149,7 @@ struct char_session_data {
 	unsigned int char_moves[MAX_CHARS]; // character moves left
 	uint8 isvip;
 	time_t unban_time[MAX_CHARS];
+	int charblock_timer;
 };
 
 struct startitem {
@@ -1148,10 +1149,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 	{
 		p.last_point.map = mapindex_name2id(last_map);
 		sd->found_char[p.slot] = p.char_id;
-		if(p.unban_time > time(NULL))
-			sd->unban_time[p.slot] = p.unban_time;
-		else if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", char_db, p.char_id) )
-			Sql_ShowDebug(sql_handle);
+		sd->unban_time[p.slot] = p.unban_time;
 		j += mmo_char_tobuf(WBUFP(buf, j), &p);
 
 		// Addon System
@@ -1954,41 +1952,85 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 	return 106+offset;
 }
 
+
+
 //----------------------------------------
 // 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) = (sd->char_slots>3)?sd->char_slots/3:1; //int TotalCnt (nb page to load)
+	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, len=4;
+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;
 
-	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //should we use MAX_CHARS or sd->charslot
-	if(i < MAX_CHARS){	
-		WFIFOHEAD(fd, 4+MAX_CHARS*24);
-		WFIFOW(fd, 0) = 0x20d;
-
-		for(i=0; i<MAX_CHARS; i++){
+	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+i*24) = sd->found_char[i];
+				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+i*24),szExpireDate,20);
-				len+=24;
+				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", 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);
+	}
+	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);
 	}
 }
 
@@ -2957,7 +2999,7 @@ int mapif_parse_reqcharban(int fd){
 	if (RFIFOREST(fd) < 10+NAME_LENGTH)
 		return 0;
 	else {
-		int aid = RFIFOL(fd,2);
+		//int aid = RFIFOL(fd,2); aid of player who as requested the ban
 		int timediff = RFIFOL(fd,6);
 		const char* name = (char*)RFIFOP(fd,10); // name of the target character
 		RFIFOSKIP(fd,10+NAME_LENGTH);
@@ -3006,12 +3048,12 @@ int mapif_parse_reqcharban(int fd){
 			if( unban_time > now ) { 
 					unsigned char buf[11];
 					WBUFW(buf,0) = 0x2b14;
-					WBUFL(buf,2) = t_aid;
+					WBUFL(buf,2) = t_cid;
 					WBUFB(buf,6) = 2;
 					WBUFL(buf,7) = (unsigned int)unban_time;
 					mapif_sendall(buf, 11);
 					// disconnect player if online on char-server
-					disconnect_player(aid);
+					disconnect_player(t_aid);
 			}
 		}
 	}

+ 6 - 7
src/map/chrif.c

@@ -1030,18 +1030,19 @@ int chrif_deadopt(int father_id, int mother_id, int child_id) {
  * Disconnection of a player (account has been banned of has a status, from login/char-server) by [Yor]
  *------------------------------------------*/
 int chrif_ban(int fd) {
-	int acc, res=0;
+	int id, res=0;
 	struct map_session_data *sd;
 
-	acc = RFIFOL(fd,2);
+	id = RFIFOL(fd,2);
 	res = RFIFOB(fd,6); // 0: change of statut, 1: ban, 2 charban
 
 	if ( battle_config.etc_log )
-		ShowNotice("chrif_ban %d.type = %s \n", acc, res==1?"account":"char");
+		ShowNotice("chrif_ban %d.type = %s \n", id, res==1?"account":"char");
 
-	sd = map_id2sd(acc);
+	if(res==2)  sd = map_charid2sd(id);
+	else sd = map_id2sd(id);
 
-	if ( acc < 0 || sd == NULL ) {
+	if ( id < 0 || sd == NULL ) {
 		//nothing to do on map if player not connected
 		return 0;
 	}
@@ -1064,8 +1065,6 @@ int chrif_ban(int fd) {
 		safesnprintf(tmpstr,sizeof(tmpstr),msg_txt(sd,423),res==2?"char":"account",strtime); //"Your %s has been banished until %s "
 		clif_displaymessage(sd->fd, tmpstr);
 	}
-	if(res == 2 && !map_charid2sd(sd->status.char_id)) //only disconect if char is online
-		return 0;
 
 	set_eof(sd->fd); // forced to disconnect for the change
 	map_quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]