Explorar o código

Fixed online system, online column works and prevent double login at the login server

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@392 54d463be-8e91-2dee-dedb-b68131a5f0ec
wizputer %!s(int64=20) %!d(string=hai) anos
pai
achega
e9b593218a
Modificáronse 6 ficheiros con 183 adicións e 48 borrados
  1. 1 0
      Changelog.txt
  2. 84 20
      src/char_sql/char.c
  3. 56 0
      src/login_sql/login.c
  4. 35 1
      src/map/chrif.c
  5. 2 0
      src/map/chrif.h
  6. 5 27
      src/map/map.c

+ 1 - 0
Changelog.txt

@@ -1,5 +1,6 @@
 Date	Added
 11/27
+	* Fixed online system, online column works and prevent double login at the login server [Wizputer]
 	* Fixed some compile time errors associated with showmsg [MouseJstr]
 	* Added get_svn_revision() in core.c [MC Cameri]
 	  -Only if you have the file .svn\entries, it will show the revision # at runtime.

+ 84 - 20
src/char_sql/char.c

@@ -149,6 +149,64 @@ int GM_num = 0;
 
 int console = 0;
 
+//-------------------------------------------------
+// Set Character online/offline [Wizputer]
+//-------------------------------------------------
+
+void set_char_online(int char_id, int account_id) {
+    if ( char_id != 99 ) {
+        sprintf(tmp_sql, "UPDATE `%s` SET `online`='1' WHERE `char_id`='%d'",char_db,char_id);
+		if (mysql_query(&mysql_handle, tmp_sql)) {
+			printf("DB server Error (set char online)- %s\n", mysql_error(&mysql_handle));
+		}
+    }		
+    
+    WFIFOW(login_fd,0) = 0x272b;
+	WFIFOL(login_fd,2) = account_id;
+	WFIFOSET(login_fd,6);
+        
+}
+
+void set_all_offline(void) {
+	sprintf(tmp_sql, "SELECT `account_id` FROM `%s` WHERE `online` = '1'",char_db);
+	if (mysql_query(&mysql_handle, tmp_sql)) {
+		printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
+	}
+		
+	sql_res = mysql_store_result(&mysql_handle);
+	if (sql_res) {
+	    while((sql_row = mysql_fetch_row(sql_res))) {
+	        if ( login_fd > 0 ) {
+	            WFIFOW(login_fd,0) = 0x272c;
+	            WFIFOL(login_fd,2) = atol(sql_row[0]);
+	            WFIFOSET(login_fd,6);
+            }
+       }
+    } 
+            
+    sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
+	if (mysql_query(&mysql_handle, tmp_sql)) {
+		printf("DB server Error (insert `char`)- %s\n", mysql_error(&mysql_handle));
+	}
+	
+	mysql_free_result(sql_res);
+}
+
+void set_char_offline(int char_id, int account_id) {
+    if ( char_id == 99 )
+        sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", char_db, account_id);
+    else
+	    sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `char_id`='%d'", char_db, char_id);
+	    
+	if (mysql_query(&mysql_handle, tmp_sql))
+		printf("DB server Error (update online `%s`)- %s\n", char_db, mysql_error(&mysql_handle));
+
+   WFIFOW(login_fd,0) = 0x272c;
+   WFIFOL(login_fd,2) = account_id;
+   WFIFOSET(login_fd,6);
+
+}       
+
 //-----------------------------------------------------
 // Function to suppress control characters in a string.
 //-----------------------------------------------------
@@ -853,10 +911,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
 	p->global_reg_num=i;
 
 	if (online) {
-		sprintf(tmp_sql, "UPDATE `%s` SET `online`='%d' WHERE `char_id`='%d'",char_db,online,char_id);
-		if (mysql_query(&mysql_handle, tmp_sql)) {
-			printf("DB server Error (set char online)- %s\n", mysql_error(&mysql_handle));
-		}
+		set_char_online(char_id,p->account_id);
 	}
 
 	printf("global_reg]\n");	//ok. all data load successfuly!
@@ -912,10 +967,7 @@ int mmo_char_sql_init(void) {
 	} else
 		printf("set char_id_count: %d.......\n",char_id_count);
 
-	sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
-	if (mysql_query(&mysql_handle, tmp_sql)) {
-		printf("DB server Error (reset_online `%s`)- %s\n", char_db, mysql_error(&mysql_handle));
-	}
+    set_all_offline();
 	printf("init end.......\n");
 
 	return 0;
@@ -1086,6 +1138,8 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
 	printf("mmo_char_send006b start.. (account:%d)\n",sd->account_id);
 //	printf("offset -> %d...\n",offset);
 
+    set_char_online(99,sd->account_id);
+
 	//search char.
 	sprintf(tmp_sql, "SELECT `char_id` FROM `%s` WHERE `account_id` = '%d'",char_db, sd->account_id);
 	if (mysql_query(&mysql_handle, tmp_sql)) {
@@ -1896,11 +1950,23 @@ int parse_frommap(int fd) {
 			if (RFIFOREST(fd) < 6 )
 				return 0;
 			//printf("Setting %d char offline\n",RFIFOL(fd,2));
-			sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `char_id`='%d'", char_db, RFIFOL(fd,2));
-			if (mysql_query(&mysql_handle, tmp_sql))
-				printf("DB server Error (update online `%s`)- %s\n", char_db, mysql_error(&mysql_handle));
-			RFIFOSKIP(fd,6);
+			set_char_offline(RFIFOL(fd,2),RFIFOL(fd,6));
+			RFIFOSKIP(fd,10);
+			break;
+		// Reset all chars to offline [Wizputer]
+		case 0x2b18:
+		    set_all_offline();
+			RFIFOSKIP(fd,2);
 			break;
+		// Character set online [Wizputer]
+		case 0x2b19:
+			if (RFIFOREST(fd) < 6 )
+				return 0;
+			//printf("Setting %d char online\n",RFIFOL(fd,2));
+			set_char_online(RFIFOL(fd,2),RFIFOL(fd,6));
+			RFIFOSKIP(fd,10);
+			break;
+		          
 		default:
 			// inter server - packet
 			{
@@ -1980,18 +2046,19 @@ int parse_char(int fd) {
 	struct char_session_data *sd;
 	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr;
 
-	if(login_fd < 0)
+	sd = session[fd]->session_data;
+	
+    if(login_fd < 0)
 		session[fd]->eof = 1;
 	if(session[fd]->eof) {
 		if (fd == login_fd)
 			login_fd = -1;
+		set_char_offline(99,sd->account_id);
 		close(fd);
 		delete_session(fd);
 		return 0;
 	}
 
-	sd = session[fd]->session_data;
-
 	while(RFIFOREST(fd) >= 2) {
 		cmd = RFIFOW(fd,0);
 		// crc32‚̃XƒLƒbƒv—p
@@ -2108,7 +2175,7 @@ int parse_char(int fd) {
 			sql_row = mysql_fetch_row(sql_res);
 
 			if (sql_row)
-				mmo_char_fromsql(atoi(sql_row[0]), char_dat, 0);
+				mmo_char_fromsql(atoi(sql_row[0]), char_dat, 1);
 			else {
 				mysql_free_result(sql_res);
 				RFIFOSKIP(fd, 3);
@@ -2693,10 +2760,7 @@ void do_final(void) {
 		sleep (0);
 	}while (save_flag != 0);
 
-	sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
-	if (mysql_query(&mysql_handle, tmp_sql)) {
-		printf("DB server Error (insert `char`)- %s\n", mysql_error(&mysql_handle));
-	}
+	set_all_offline();
 
 	sprintf(tmp_sql,"DELETE FROM `ragsrvinfo");
 	if (mysql_query(&mysql_handle, tmp_sql)) {

+ 56 - 0
src/login_sql/login.c

@@ -137,6 +137,39 @@ int auth_fifo_pos = 0;
 
 static char md5key[20], md5keylen = 16;
 
+struct dbt *online_db;
+
+//-----------------------------------------------------
+// Online User Database [Wizputer]
+//-----------------------------------------------------
+
+void add_online_user(int account_id) {
+    int *p;
+    p = malloc(sizeof(int));
+    if (p == NULL) {
+		printf("add_online_user: memory allocation failure (malloc)!\n");
+		exit(0);
+	}
+	p = &account_id;
+    numdb_insert(online_db, account_id, p);
+}
+
+int is_user_online(int account_id) {
+    int *p;
+
+	p = numdb_search(online_db, account_id);
+	if (p == NULL)
+		return 0;
+	printf("Acccount %d\n",*p);
+	return 1;
+}
+
+void remove_online_user(int account_id) {
+    int *p;
+    p = numdb_erase(online_db,account_id);
+    free(p);
+}
+
 //-----------------------------------------------------
 // check user level
 //-----------------------------------------------------
@@ -528,6 +561,11 @@ int mmo_auth( struct mmo_account* account , int fd){
 		return 2; // 2 = This ID is expired
 	}
 
+    if ( is_user_online(atol(sql_row[0])) ) {
+        printf("User [%s] is already online - Rejected.\n",sql_row[1]);
+	    return 3; // Rejected
+    }
+        
 	account->account_id = atoi(sql_row[0]);
 	account->login_id1 = rand();
 	account->login_id2 = rand();
@@ -989,6 +1027,20 @@ int parse_fromchar(int fd){
 			}
 			return 0;
 			
+    case 0x272b:    // Set account_id to online [Wizputer]
+        if (RFIFOREST(fd) < 6)
+            return 0;
+        add_online_user(RFIFOL(fd,2));
+        RFIFOSKIP(fd,6);
+        break;
+    
+    case 0x272c:   // Set account_id to offline [Wizputer]
+        if (RFIFOREST(fd) < 6)
+            return 0;
+        remove_online_user(RFIFOL(fd,2));
+        RFIFOSKIP(fd,6);
+        break;
+			
 	default:
 		printf("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
 		session[fd]->eof = 1;
@@ -1756,6 +1808,10 @@ int do_init(int argc,char **argv){
 		start_console();
 	}
 	
+	// Online user database init
+    free(online_db);
+	online_db = numdb_init();
+	
 	printf("The login-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n", login_port);
 
 	return 0;

+ 35 - 1
src/map/chrif.c

@@ -904,11 +904,45 @@ int chrif_char_offline(struct map_session_data *sd)
 
 	WFIFOW(char_fd,0) = 0x2b17;
 	WFIFOL(char_fd,2) = sd->status.char_id;
-	WFIFOSET(char_fd,6);
+	WFIFOL(char_fd,6) = sd->status.account_id;
+	WFIFOSET(char_fd,10);
+
+	return 0;
+}
+
+/*=========================================
+ * Tell char-server to reset all chars offline [Wizputer]
+ *-----------------------------------------
+ */
+int chrif_char_reset_offline(void) {
+	if (char_fd < 0)
+		return -1;
+
+	WFIFOW(char_fd,0) = 0x2b18;
+	WFIFOSET(char_fd,2);
 
 	return 0;
 }
 
+/*=========================================
+ * Tell char-server charcter is online [Wizputer]
+ *-----------------------------------------
+ */
+
+int chrif_char_online(struct map_session_data *sd) 
+{
+	if (char_fd < 0)
+		return -1;
+
+	WFIFOW(char_fd,0) = 0x2b19;
+	WFIFOL(char_fd,2) = sd->status.char_id;
+	WFIFOL(char_fd,6) = sd->status.account_id;
+	WFIFOSET(char_fd,10);
+
+	return 0;
+}
+
+
 /*==========================================
  *
  *------------------------------------------

+ 2 - 0
src/map/chrif.h

@@ -23,6 +23,8 @@ int chrif_saveaccountreg2(struct map_session_data *sd);
 int chrif_reloadGMdb(void);
 int chrif_ragsrvinfo(int base_rate,int job_rate, int drop_rate);
 int chrif_char_offline(struct map_session_data *sd);
+int chrif_char_reset_offline(void);
+int chrif_char_online(struct map_session_data *sd);
 int chrif_changesex(int id, int sex);
 int chrif_chardisconnect(struct map_session_data *sd);
 

+ 5 - 27
src/map/map.c

@@ -1570,8 +1570,8 @@ static int map_readmap(int m,char *fn, char *alias) {
 	if(gat==NULL)
 		return -1;
 
-//	printf("\rLoading Maps [%d/%d]: %-50s  ",m,map_num,fn);
-//	fflush(stdout);
+	printf("\rLoading Maps [%d/%d]: %-50s  ",m,map_num,fn);
+	fflush(stdout);
 
 	map[m].m=m;
 	xs=map[m].xs=*(int*)(gat+6);
@@ -2054,25 +2054,6 @@ int sql_config_read(char *cfgName)
 	return 0;
 }
 
-// sql online status checking [Valaris]
-void char_offline(struct map_session_data *sd)
-{
-	if(sd && sd->status.char_id) {
-		sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `char_id`='%d'", char_db, sd->status.char_id);
-	        if(mysql_query(&mmysql_handle, tmp_sql) ) {
-			printf("DB server Error (update online `%s`)- %s\n", char_db, mysql_error(&mmysql_handle) );
-	        }
-	}
-}
-
-void do_reset_online(void)
-{
-	sprintf(tmp_sql,"UPDATE `%s` SET `online`='0' WHERE `online`='1'", char_db);
-	if(mysql_query(&mmysql_handle, tmp_sql) ) {
-		printf("DB server Error (reset_online `%s`)- %s\n", char_db, mysql_error(&mmysql_handle) );
-	}
-}
-
 int online_timer(int tid,unsigned int tick,int id,int data)
 {
 	if(check_online_timer != tid)
@@ -2090,16 +2071,13 @@ void char_online_check(void)
 	int i;
 	struct map_session_data *sd=NULL;
 
-	do_reset_online();
+	chrif_char_reset_offline();
 
 	for(i=0;i<fd_max;i++){
 		if (session[i] && (sd = session[i]->session_data) && sd && sd->state.auth && 
 		 !(battle_config.hide_GM_session && pc_isGM(sd)))
 			if(sd->status.char_id) {
-				sprintf(tmp_sql,"UPDATE `%s` SET `online`='1' WHERE `char_id`='%d'", char_db, sd->status.char_id);
-			        if(mysql_query(&mmysql_handle, tmp_sql) ) {
-					printf("DB server Error (update online `%s`)- %s\n", char_db, mysql_error(&mmysql_handle) );
-				}
+				 chrif_char_online(sd);
 			}
 	}
 
@@ -2199,7 +2177,7 @@ void do_final(void) {
 	do_final_storage();
         do_final_guild();
 #ifndef TXT_ONLY
-	do_reset_online();
+	chrif_char_reset_offline();
     map_sql_close();
 #endif /* not TXT_ONLY */
 }