Sfoglia il codice sorgente

QuickFix for charban

Fixing charban causing segfault on charserv
Fixing charban wrong target
Fixing charban not able to ban unconnected char
Fixing charblock being sent before unban_time was filled
Reset unban_time to 0 when < now.
lighta 11 anni fa
parent
commit
82b272f410
7 ha cambiato i file con 68 aggiunte e 61 eliminazioni
  1. 46 40
      src/char/char.c
  2. 2 2
      src/map/atcommand.c
  3. 2 2
      src/map/battle.c
  4. 15 11
      src/map/chrif.c
  5. 1 1
      src/map/chrif.h
  6. 2 3
      src/map/pc.c
  7. 0 2
      src/map/script.c

+ 46 - 40
src/char/char.c

@@ -1087,6 +1087,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 
 	for( i = 0; i < MAX_CHARS; i++ ){
 		sd->found_char[i] = -1;
+		sd->unban_time[i] = 0;
 	}
 
 	// read char data
@@ -1147,7 +1148,10 @@ 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;
-		sd->unban_time[p.slot] = p.unban_time;
+		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);
 		j += mmo_char_tobuf(WBUFP(buf, j), &p);
 
 		// Addon System
@@ -1967,18 +1971,17 @@ void char_charlist_notify( int fd, struct char_session_data* sd ){
  */
 void char_block_character( int fd, struct char_session_data* sd ){
 	int i=0, len=4;
-	char szExpireDate[20];
 	time_t now = time(NULL);
 
 	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //should we use MAX_CHARS or sd->charslot
-	if(i < MAX_CHARS){
-		memset(szExpireDate,'\0',20);
+	if(i < MAX_CHARS){	
 		WFIFOHEAD(fd, 4+MAX_CHARS*24);
 		WFIFOW(fd, 0) = 0x20d;
 
 		for(i=0; i<MAX_CHARS; i++){
 			if( sd->unban_time[i] > now ) {
-				WFIFOL(fd, 4+i*24) = sd->found_char[i]; //gid
+				char szExpireDate[21];
+				WFIFOL(fd, 4+i*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;
@@ -2010,7 +2013,7 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
 	if(newvers) //20100413
 		offset += 3;
 	if (save_log)
-		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
+		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);
@@ -2038,7 +2041,7 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
 //----------------------------------------
 void mmo_char_send082d(int fd, struct char_session_data* sd) {
 	if (save_log)
-		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
+		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;
@@ -2056,11 +2059,12 @@ void mmo_char_send(int fd, struct char_session_data* sd){
 	if(sd->version > date2version(20130000) ){
 		mmo_char_send082d(fd,sd);
 		char_charlist_notify(fd,sd);
-		char_block_character(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)
@@ -2950,14 +2954,15 @@ void mapif_on_disconnect(int id)
 }
 
 int mapif_parse_reqcharban(int fd){
-	if (RFIFOREST(fd) < 10)
+	if (RFIFOREST(fd) < 10+NAME_LENGTH)
 		return 0;
-	else {	
-		int cid = RFIFOL(fd,2);
+	else {
+		int aid = RFIFOL(fd,2);
 		int timediff = RFIFOL(fd,6);
-		RFIFOSKIP(fd,10);
+		const char* name = (char*)RFIFOP(fd,10); // name of the target character
+		RFIFOSKIP(fd,10+NAME_LENGTH);
 
-		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` `unban_time` FROM `%s` WHERE `char_id` = '%d'", char_db, cid) )
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`unban_time` FROM `%s` WHERE `name` = '%s'", char_db, name) )
 			Sql_ShowDebug(sql_handle);
 		else if( Sql_NumRows(sql_handle) == 0 ){
 			return -1; // 1-player not found
@@ -2967,45 +2972,46 @@ int mapif_parse_reqcharban(int fd){
 			Sql_FreeResult(sql_handle);
 			return -1;
 		} else {
-			int aid;
+			int t_cid=0,t_aid=0;
 			char* data;
 			time_t unban_time;
+			time_t now = time(NULL);
+			SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
 
-			Sql_GetData(sql_handle, 0, &data, NULL); aid = atoi(data);
-			Sql_GetData(sql_handle, 1, &data, NULL); unban_time = atol(data);
+			Sql_GetData(sql_handle, 0, &data, NULL); t_aid = atoi(data);
+			Sql_GetData(sql_handle, 1, &data, NULL); t_cid = atoi(data);
+			Sql_GetData(sql_handle, 2, &data, NULL); unban_time = atol(data);
 			Sql_FreeResult(sql_handle);
 
-
 			if(timediff<0 && unban_time==0) return 0; //attemp to reduce time of a non banned account ?!?
-			else if(unban_time==0) unban_time=time(NULL); //new entry
-			unban_time += timediff;
+			else if(unban_time<now) unban_time=now; //new entry
+			unban_time += timediff; //alterate the time
+			if( unban_time < now ) unban_time=0; //we have totally reduce the time
+			
+			if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
+					  "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
+					  char_db)
+				|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_LONG,   (void*)&unban_time,   sizeof(unban_time))
+				|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_INT,    (void*)&t_cid,     sizeof(t_cid))
+				|| SQL_SUCCESS != SqlStmt_Execute(stmt)
+
+				) {
+				SqlStmt_ShowDebug(stmt);
+				SqlStmt_Free(stmt);
+				return -1;
+			}
+			SqlStmt_Free(stmt);
+			
 			// condition applies; send to all map-servers to disconnect the player
-			if( unban_time > time(NULL) ) {
-				unsigned char buf[11];
-				SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
-				if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
-						  "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
-						  char_db)
-					|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_LONG,   (void*)&unban_time,   sizeof(unban_time))
-					|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_INT,    (void*)&cid,     sizeof(cid))
-					|| SQL_SUCCESS != SqlStmt_Execute(stmt)
-
-					) {
-					SqlStmt_ShowDebug(stmt);
-					SqlStmt_Free(stmt);
-					return -1;
-				}
-				else {
+			if( unban_time > now ) { 
+					unsigned char buf[11];
 					WBUFW(buf,0) = 0x2b14;
-					WBUFL(buf,2) = aid;
+					WBUFL(buf,2) = t_aid;
 					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);
-				}
-				SqlStmt_Free(stmt);
 			}
 		}
 	}
@@ -3015,7 +3021,7 @@ int mapif_parse_reqcharban(int fd){
 int mapif_parse_reqcharunban(int fd){
 	if (RFIFOREST(fd) < 6)
 		return 0;
-	else {	
+	else {
 		int cid = RFIFOL(fd,2);
 		RFIFOSKIP(fd,6);
 		

+ 2 - 2
src/map/atcommand.c

@@ -2826,8 +2826,8 @@ ACMD_FUNC(char_ban)
 	
 	if(bantype==2) 
 		chrif_req_login_operation(sd->status.account_id, atcmd_player_name, 2, timediff, 0, 0); // type: 2 - ban
-	else
-		chrif_req_charban(sd->status.char_id,timediff);
+	else 
+		chrif_req_charban(sd->status.account_id, atcmd_player_name,timediff);
 	
 	safesnprintf(output,sizeof(output),msg_txt(sd,88),bantype==6?"char":"login"); // Sending request to %s server...
 	clif_displaymessage(fd, output);

+ 2 - 2
src/map/battle.c

@@ -5923,10 +5923,10 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
 					}
 				}
 
-                if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !(src->type == BL_MOB && is_boss(src)) ){
+				if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !(src->type == BL_MOB && is_boss(src)) ){
 						rdamage += damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100;
 						if (rdamage < 1) rdamage = 1;
-                }
+				}
 			}
 		}
 	} else {

+ 15 - 11
src/map/chrif.c

@@ -46,7 +46,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
 	11,10,10, 0,11, -1,266,10,	// 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, U->2b16, U->2b17
 	 2,10, 2,-1,-1,-1, 2, 7,	// 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
 	-1,10, 8, 2, 2,14,19,19,	// 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
-	10,10, 6,15, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
+	-1,10, 6,15, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
  };
 
 //Used Packets:
@@ -816,8 +816,8 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email) {
 /**
  * S 2b0e <accid>.l <name>.24B <operation_type>.w <timediff>L <val1>L <val2>L
  * Send an account modification request to the login server (via char server).
- * @aid : Player account id
- * @character_name : Player name
+ * @aid : Player requesting operation account id
+ * @character_name : Target of operation Player name
  * @operation_type : 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6 vip, 7 bank 
  * @timediff : tick to add or remove to unixtimestamp
  * @val1 : extra data value to transfer for operation
@@ -1029,7 +1029,8 @@ 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_accountban(int fd) {
+int chrif_ban(int fd) {
+	ShowInfo("chrif_ban \n");
 	int acc, res=0;
 	struct map_session_data *sd;
 
@@ -1037,12 +1038,12 @@ int chrif_accountban(int fd) {
 	res = RFIFOB(fd,6); // 0: change of statut, 1: ban, 2 charban
 
 	if ( battle_config.etc_log )
-		ShowNotice("chrif_accountban %d.\n", acc);
+		ShowNotice("chrif_ban %d.type = %s \n", acc, res==1?"account":"char");
 
 	sd = map_id2sd(acc);
 
 	if ( acc < 0 || sd == NULL ) {
-		ShowError("chrif_accountban failed - player not online.\n");
+		//nothing to do on map if player not connected
 		return 0;
 	}
 
@@ -1064,20 +1065,23 @@ int chrif_accountban(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]
 	return 0;
 }
 
-int chrif_req_charban(int cid, int timediff){
+int chrif_req_charban(int aid, const char* character_name, int timediff){
 	chrif_check(-1);
 	
-	WFIFOHEAD(char_fd,10);
+	WFIFOHEAD(char_fd,10+NAME_LENGTH);
 	WFIFOW(char_fd,0) = 0x2b28;
-	WFIFOL(char_fd,2) = cid;
+	WFIFOL(char_fd,2) = aid;
 	WFIFOL(char_fd,6) = timediff;
-	WFIFOSET(char_fd,10);
+	safestrncpy((char*)WFIFOP(char_fd,10), character_name, NAME_LENGTH);
+	WFIFOSET(char_fd,10+NAME_LENGTH); //default 34
 	return 0;
 }
 
@@ -1610,7 +1614,7 @@ int chrif_parse(int fd) {
 			case 0x2b0d: chrif_changedsex(fd); break;
 			case 0x2b0f: chrif_ack_login_req(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
 			case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
-			case 0x2b14: chrif_accountban(fd); break;
+			case 0x2b14: chrif_ban(fd); break;
 			case 0x2b1b: chrif_recvfamelist(fd); break;
 			case 0x2b1d: chrif_load_scdata(fd); break;
 			case 0x2b1e: chrif_update_ip(fd); break;

+ 1 - 1
src/map/chrif.h

@@ -67,7 +67,7 @@ int chrif_send_report(char* buf, int len);
 
 void chrif_parse_ack_vipActive(int fd);
 
-int chrif_req_charban(int aid, int timediff);
+int chrif_req_charban(int aid, const char* character_name, int timediff);
 int chrif_req_charunban(int cid);
 
 int chrif_load_bankdata(int fd);

+ 2 - 3
src/map/pc.c

@@ -8485,8 +8485,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data) {
 	int index, idx, success = 0;
 
 	for( i = 0; i < data->combos_count; i++ ) {
-		int *combo_idx = NULL;
-		
+		int16 *combo_idx = NULL;
 		/* ensure this isn't a duplicate combo */
 		if( sd->combos.bonus != NULL ) {
 			int x;
@@ -8497,7 +8496,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data) {
 				continue;
 		}
 
-		combo_idx = CREATE(combo_idx,int,data->combos[i]->count);
+		CREATE(combo_idx,int16,data->combos[i]->count);
 		for( j = 0; j < data->combos[i]->count; j++ ) {
 			int id = data->combos[i]->nameid[j];
 			bool found = false;

+ 0 - 2
src/map/script.c

@@ -18650,9 +18650,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(getserverdef,"i"),
 	BUILDIN_DEF2(montransform, "transform", "vii????"), // Monster Transform [malufett/Hercules]
 	BUILDIN_DEF(vip_status,"i?"),
-#ifdef VIP_ENABLE
 	BUILDIN_DEF(vip_time,"i?"),
-#endif
 	BUILDIN_DEF(bonus_script,"si???"),
 
 #include "../custom/script_def.inc"