summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorwizputer <wizputer@54d463be-8e91-2dee-dedb-b68131a5f0ec>2004-12-10 06:00:44 +0000
committerwizputer <wizputer@54d463be-8e91-2dee-dedb-b68131a5f0ec>2004-12-10 06:00:44 +0000
commitf7ca47e0e6c972cd826a2bba6380434ae61ce737 (patch)
treef5833ff557a0625d2d884cab58fec8fcaacad8fd /src
parentcdda13efae3c824a1d84eaf3a02382c83d09f1df (diff)
downloadhercules-f7ca47e0e6c972cd826a2bba6380434ae61ce737.tar.gz
hercules-f7ca47e0e6c972cd826a2bba6380434ae61ce737.tar.bz2
hercules-f7ca47e0e6c972cd826a2bba6380434ae61ce737.tar.xz
hercules-f7ca47e0e6c972cd826a2bba6380434ae61ce737.zip
* char-server -UNTESTED- [Wizputer]
* new method for getting GMs [Wizputer] * Added unique key for Char names [Wizputer] git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@529 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/char_sql/char.c1071
-rw-r--r--src/login_sql/login.c45
2 files changed, 595 insertions, 521 deletions
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index f9a70be29..6375c2602 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -155,6 +155,11 @@ int console = 0;
char prev_query[65535];
+char servers_connected = 0;
+
+// GM Database
+struct dbt *gm_db;
+
//----------------------------------------------
//SQL Commands ( Original by Clownisius ) [Edit: Wizputer]
//----------------------------------------------
@@ -198,36 +203,66 @@ int remove_control_chars(unsigned char *str) {
// and returns its level (or 0 if it isn't a GM account or if not found)
//----------------------------------------------------------------------
// Removed since nothing GM related goes on in the char server [CLOWNISIUS]
-int isGM(int account_id) {
- int i;
- for(i = 0; i < GM_num; i++)
- if (gm_account[i].account_id == account_id)
- return gm_account[i].level;
- return 0;
+unsigned char isGM(int account_id) {
+ unsigned char *level;
+
+ level = numdb_search(gm_db, account_id);
+ if (level == NULL)
+ return 0;
+
+ return *level;
}
-void read_gm_account(void) {
- if (gm_account != NULL)
- free(gm_account);
- GM_num = 0;
+static int gmdb_final(void *key,void *data,va_list ap) {
+ unsigned char *level;
- sprintf(tmp_lsql, "SELECT `%s`,`%s` FROM `%s` WHERE `%s`>='%d'",login_db_account_id,login_db_level,login_db,login_db_level,lowest_gm_level);
- if (mysql_query(&lmysql_handle, tmp_lsql)) {
- printf("DB server Error (select %s to Memory)- %s\n",login_db,mysql_error(&lmysql_handle));
- return;
- }
- lsql_res = mysql_store_result(&lmysql_handle);
- if (lsql_res) {
- gm_account = calloc(sizeof(struct gm_account) * mysql_num_rows(lsql_res), 1);
- while ((lsql_row = mysql_fetch_row(lsql_res))) {
- gm_account[GM_num].account_id = atoi(lsql_row[0]);
- gm_account[GM_num].level = atoi(lsql_row[1]);
- GM_num++;
- }
+ nullpo_retr(0, level=data);
+
+ free(level);
+
+ return 0;
+}
+
+void do_final_gmdb(void) {
+ if(gm_db){
+ numdb_final(gm_db,gmdb_final);
+ gm_db=NULL;
}
+}
+
+void read_gm_accounts(int fd, int len) {
+ GM_num = RFIFOW(fd,2);
+
+ if(len < (6+5*GM_num))
+ return;
+
+ int i=0,account_id=0;
+ unsigned char level*;
+
+ if (gm_db)
+ do_final_gmdb();
+
+ gm_db = numdb_init();
- mysql_free_result(lsql_res);
+ WFIFOW(fd,0) = 0x2b99;
+ WFIFOW(fd,2) = GM_num;
+
+ if(GM_num) {
+ for(i=0;i<GM_num;i++) {
+ level = malloc(sizeof(unsigned char));
+
+ *level = RFIFOB(fd,(10+5*(GM_num-1));
+ account_id = RFIFOW(fd,(6+5*(GM_num-1))
+
+ numdb_insert(gm_db, account_id, level);
+
+ WFIFOL(fd,6+5*i) = account_id;
+ WFIFOB(fd,10+5*i) = *level;
+ }
+ }
+
+ WFIFOSET(fd,6+5*i);
}
//=====================================================================================================
@@ -244,7 +279,9 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
#ifdef DEBUG
printf("(\033[1;32m%d\033[0m) %s \trequest save char data - ",char_id,char_dat[0].name);
#endif
-
+
+ sql_query("START TRANSACTION","mmo_char_tosql");
+
//=========================================map inventory data > memory ===============================
//map inventory data
for(i=0;i<MAX_INVENTORY;i++){
@@ -351,7 +388,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
printf("Char [%s] - Saved Char data to SQL!\n",p->name);
#endif
- sprintf(tmp_sql,"REPLACE INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ",memo_db);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",memo_db,char_id);
+ sql_query(tmp_sql,"mmo_char_tosql");
+
+ sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`,`map`,`x`,`y`) VALUES ",memo_db);
for(i=0;i<10;i++){
if(i)
sprintf(tmp_sql,"%s,",tmp_sql);
@@ -367,7 +407,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
printf("Char [%s] - Saved memo data to SQL!\n",p->name);
#endif
- sprintf(tmp_sql,"REPLACE INTO `%s`(`char_id`, `id`, `lv`) VALUES ",skill_db);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d'",skill_db,char_id);
+ sql_query(tmp_sql,"mmo_char_tosql");
+
+ sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`, `id`, `lv`) VALUES ",skill_db);
for(i=0;i<MAX_SKILL;i++){
if(p->skill[i].id){
if (p->skill[i].id && p->skill[i].flag!=1) {
@@ -386,7 +429,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
printf("Char [%s] - Save skill data to SQL!\n",p->name);
#endif
- sprintf(tmp_sql,"REPLACE INTO `%s`(`char_id`, `str`, `value`) VALUES ",reg_db);
+ sprintf(tmp_sql,"DELETE FROM `%s` WHERE `char_id`='%d' AND `type`='3'",reg_db,char_id);
+ sql_query(tmp_sql,"mmo_char_tosql");
+
+ sprintf(tmp_sql,"INSERT INTO `%s`(`char_id`, `str`, `value`) VALUES ",reg_db);
for(i=0;i<p->global_reg_num;i++){
if (p->global_reg[i].str) {
if(p->global_reg[i].value !=0){
@@ -401,6 +447,8 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){
sql_query(tmp_sql,"mmo_char_tosql");
+ sql_query("COMMIT","mmo_char_tosql");
+
#ifdef DEBUG
printf("Char [%s] - Save global reg data to SQL!\n",p->name);
printf("Char [%s] - Saving char is done.\n",p->name);
@@ -699,9 +747,10 @@ int memitemdata_to_sql(struct itemtemp mapitem, int eqcount, int noteqcount, int
}
return 0;
}
+
//=====================================================================================================
int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
- int i, n;
+ int i=0, n=0;
memset(p, 0, sizeof(struct mmo_charstatus));
@@ -850,7 +899,8 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
if ((sql_res = mysql_store_result(&mysql_handle))) {
for(i=0;(sql_row = mysql_fetch_row(sql_res));i++){
- p->skill[n].id = atoi(sql_row[0]);
+ n = atoi(sql_row[0]);
+ p->skill[n].id = n;
p->skill[n].lv = atoi(sql_row[1]);
}
mysql_free_result(sql_res);
@@ -889,56 +939,47 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p, int online){
}
//==========================================================================================================
int mmo_char_sql_init(void) {
- int i;
+ int i=0;
- printf("init start.......\n");
// memory initialize
// no need to set twice size in this routine. but some cause segmentation error. :P
- printf("initializing char memory...(%d byte)\n",sizeof(struct mmo_charstatus)*2);
+ #ifdef DEBUG
+ printf("Initializing char memory...(%d byte)\n",sizeof(struct mmo_charstatus)*2);
+ #endif
+
CREATE(char_dat, struct mmo_charstatus, 2);
-
memset(char_dat, 0, sizeof(struct mmo_charstatus)*2);
-/* Initialized in inter.c already [Wizputer]
- // DB connection initialized
- // for char-server session only
- mysql_init(&mysql_handle);
- printf("Connect DB server....(char server)\n");
- if(!mysql_real_connect(&mysql_handle, char_server_ip, char_server_id, char_server_pw, char_server_db ,char_server_port, (char *)NULL, CLIENT_MULTI_STATEMENTS)) {
- // SQL connection pointer check
- printf("%s\n",mysql_error(&mysql_handle));
- exit(1);
- } else {
- printf("connect success! (char server)\n");
- }
-*/
+
sprintf(tmp_sql , "SELECT count(*) FROM `%s`", char_db);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- }
- sql_res = mysql_store_result(&mysql_handle) ;
- sql_row = mysql_fetch_row(sql_res);
- printf("total char data -> '%s'.......\n",sql_row[0]);
- i = atoi (sql_row[0]);
- mysql_free_result(sql_res);
+ sql_query(tmp_sql,"mmo_char_sql_init");
+
+ if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ i = atoi (sql_row[0]);
+ #ifdef DEBUG
+ printf("Total number of chars in DB [%d]\n",i);
+ #endif
+ }
+
+ mysql_free_result(sql_res);
if (i !=0) {
sprintf(tmp_sql , "SELECT max(`char_id`) FROM `%s`", char_db);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- }
- sql_res = mysql_store_result(&mysql_handle) ;
- sql_row = mysql_fetch_row(sql_res);
- char_id_count = atoi (sql_row[0]);
-
+ sql_query(tmp_sql,"mmo_char_sql_init");
+
+ if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res)))
+ char_id_count = atoi (sql_row[0]);
+
mysql_free_result(sql_res);
- } 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));
- }
- printf("init end.......\n");
+ #ifdef DEBUG
+ printf("Highest Char ID [%d]\n",char_id_count);
+ } else {
+ printf("Highest Char ID [%d]\n",char_id_count);
+ #endif
+ }
+
+ #ifdef DEBUG
+ printf("Init finsihed\n");
+ #endif
return 0;
}
@@ -949,9 +990,13 @@ int make_new_char_sql(int fd, unsigned char *dat) {
struct char_session_data *sd;
char t_name[100];
int i;
+
//aphostropy error check! - fixed!
jstrescapecpy(t_name, dat);
- printf("making new char -");
+
+ #ifdef DEBUG
+ printf("Making new char [%s]\n",dat);
+ #endif
sd = session[fd]->session_data;
@@ -968,8 +1013,7 @@ int make_new_char_sql(int fd, unsigned char *dat) {
//check stat error
if ((dat[24]+dat[25]+dat[26]+dat[27]+dat[28]+dat[29]!=5*6 ) ||
- (dat[30] >= 9) ||
- (dat[33] <= 0) || (dat[33] >= 20) ||
+ (dat[30] >= 9) || (dat[33] <= 0) || (dat[33] >= 20) ||
(dat[31] >= 9)) {
// check individual stat value
@@ -980,111 +1024,76 @@ int make_new_char_sql(int fd, unsigned char *dat) {
}
// char.log to charlog
- sprintf(tmp_sql,"INSERT INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
+ sprintf(tmp_sql,"INSERT DELAYED INTO `%s` (`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
"VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
charlog_db,"make new char error", sd->account_id, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
//query
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- }
- printf("make new char error %d-%d %s %d, %d, %d, %d, %d, %d %d, %d" RETCODE,
+ sql_query(tmp_sql,"amke_new_char_sql");
+
+ #ifdef DEBUG
+ printf("Make new char error %d-%d %s %d, %d, %d, %d, %d, %d %d, %d" RETCODE,
fd, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
+ #endif
+
return -1;
}
// char.log to charlog
- sprintf(tmp_sql,"INSERT INTO `%s`(`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
+ sprintf(tmp_sql,"INSERT DELAYED INTO `%s`(`time`, `char_msg`,`account_id`,`char_num`,`name`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hair`,`hair_color`)"
"VALUES (NOW(), '%s', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
charlog_db,"make new char", sd->account_id, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
//query
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- }
+ sql_query(tmp_sql,"make_new_char_sql");
+
+ #ifdef DEBUG
printf("make new char %d-%d %s %d, %d, %d, %d, %d, %d - %d, %d" RETCODE,
fd, dat[30], dat, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29], dat[33], dat[31]);
-
- sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `name` = '%s'",char_db, t_name);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- return -1;
- }
- sql_res = mysql_store_result(&mysql_handle);
- sql_row = mysql_fetch_row(sql_res);
- printf("\033[1;32m name check result : %s -\033[0m ",sql_row[0]);
- if (atoi(sql_row[0]) > 0) {
- mysql_free_result(sql_res);
- return -1;
- } else
- mysql_free_result(sql_res);
-
+ #endif
+
// check char slot.
sprintf(tmp_sql, "SELECT count(*) FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d'",char_db, sd->account_id, dat[30]);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
+ sql_query(tmp_sql,"make_new_char_sql");
+
+ if((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ if (atoi(sql_row[0]) > 0) {
+ mysql_free_result(sql_res);
+ return -1;
+ } else
+ mysql_free_result(sql_res);
}
- sql_res = mysql_store_result(&mysql_handle);
- sql_row = mysql_fetch_row(sql_res);
-
- //printf("slot check result : %s\n",sql_row[0]);
- if (atoi(sql_row[0]) > 0) {
- mysql_free_result(sql_res);
- return -1;
- } else
- mysql_free_result(sql_res);
-
+
char_id_count++;
// make new char.
- sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`account_id`,`char_num`,`name`,`zeny`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,`hair`,`hair_color`)"
- " VALUES ('%d', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d')",
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`account_id`,`char_num`,`name`,`zeny`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,"
+ "`max_hp`,`hp`,`max_sp`,`sp`,`hair`,`hair_color`,`last_map`,`last_x`,`last_y`,`save_map`,`save_x`,`save_y`)"
+ " VALUES ('%d', '%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d','%s','%d','%d','%s','%d','%d')",
char_db, char_id_count, sd->account_id , dat[30] , t_name, start_zeny, dat[24], dat[25], dat[26], dat[27], dat[28], dat[29],
- (40 * (100 + dat[26])/100) , (40 * (100 + dat[26])/100 ), (11 * (100 + dat[27])/100), (11 * (100 + dat[27])/100), dat[33], dat[31]);
+ (40 * (100 + dat[26])/100) , (40 * (100 + dat[26])/100 ), (11 * (100 + dat[27])/100), (11 * (100 + dat[27])/100), dat[33], dat[31],
+ start_point.map,start_point.x,start_point.y, start_point.map,start_point.x,start_point.y);
if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (insert `char`)- %s\n", mysql_error(&mysql_handle));
+ printf("DB server Error (insert new char into `char`)- %s\n", mysql_error(&mysql_handle));
+ return -1;
}
//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
- sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')",
- inventory_db, char_id_count, 1201,1,0x02,1); //add Knife
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (insert `inventory`)- %s\n", mysql_error(&mysql_handle));
- }
+ sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d'),('%d', '%d', '%d', '%d', '%d')",
+ inventory_db, char_id_count, 1201,1,0x02,1,char_id_count,2301,1,0x10,1); //add Knife and Cotton Shirt
+ sql_query(tmp_sql,"make_new_char_sql");
- sprintf(tmp_sql,"INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `equip`, `identify`) VALUES ('%d', '%d', '%d', '%d', '%d')",
- inventory_db, char_id_count, 2301,1,0x10,1); //add Cotton Shirt
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (insert `inventory`)- %s\n", mysql_error(&mysql_handle));
- }
- // respawn map and start point set
- sprintf(tmp_sql,"UPDATE `%s` SET `last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d' WHERE `char_id` = '%d'",
- char_db, start_point.map,start_point.x,start_point.y, start_point.map,start_point.x,start_point.y, char_id_count);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (update `char`)- %s\n", mysql_error(&mysql_handle));
- }
- printf("making new char success - id:(\033[1;32m%d\033[0m\tname:\033[1;32%s\033[0m\n", char_id_count, t_name);
+ #ifdef DEBUG
+ printf("Make new char success - id:(\033[1;32m%d\033[0m\tname:\033[1;32%s\033[0m\n", char_id_count, t_name);
+ #endif
+
return char_id_count;
}
-//==========================================================================================================
-
-void mmo_char_sync(void){
- printf("mmo_char_sync() - nothing to do\n");
-}
-
-// to do
-///////////////////////////
-
-int mmo_char_sync_timer(int tid, unsigned int tick, int id, int data) {
- printf("mmo_char_sync_timer() tic - no works to do\n");
- return 0;
-}
-
int count_users(void) {
int i, users;
if (login_fd > 0 && session[login_fd]){
users = 0;
- for(i = 0; i < MAX_MAP_SERVERS; i++) {
+ for(i = 0; i < MAX_MAP_SERVERS && i < servers_connected; i++) {
if (server_fd[i] >= 0) {
users += server[i].users;
}
@@ -1112,38 +1121,34 @@ int send_users_tologin(int tid, unsigned int tick, int id, int data) {
return 0;
}
+
+
int mmo_char_send006b(int fd, struct char_session_data *sd) {
int i, j, found_num = 0;
struct mmo_charstatus *p = NULL;
-// hehe. commented other. anyway there's no need to use older version.
-// if use older packet version just uncomment that!
-//#ifdef NEW_006b
+
const int offset = 24;
-//#else
-// int offset = 4;
-//#endif
- printf("mmo_char_send006b start.. (account:%d)\n",sd->account_id);
-// printf("offset -> %d...\n",offset);
+ #ifdef DEBUG
+ printf("Send Chars (account:%d)\n",sd->account_id);
+ #endif
//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)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- }
- sql_res = mysql_store_result(&mysql_handle);
- if (sql_res) {
+ sql_query(tmp_sql,"mmo_char_send006b");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
found_num = mysql_num_rows(sql_res);
+
+ #ifdef DEBUG
printf("number of chars: %d\n", found_num);
- i = 0;
- while((sql_row = mysql_fetch_row(sql_res))) {
+ #endif
+
+ for(i=0;(sql_row = mysql_fetch_row(sql_res));i++)
sd->found_char[i] = atoi(sql_row[0]);
- i++;
- }
- mysql_free_result(sql_res);
}
-
-// printf("char fetching end (total: %d)....\n", found_num);
+
+ mysql_free_result(sql_res);
for(i = found_num; i < 9; i++)
sd->found_char[i] = -1;
@@ -1152,7 +1157,9 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
WFIFOW(fd, 0) = 0x6b;
WFIFOW(fd, 2) = offset + found_num * 106;
+ #ifdef DEBUG
printf("(\033[1;13m%d\033[0m) Request Char Data:\n",sd->account_id);
+ #endif
for(i = 0; i < found_num; i++) {
mmo_char_fromsql(sd->found_char[i], char_dat, 0);
@@ -1204,19 +1211,232 @@ int mmo_char_send006b(int fd, struct char_session_data *sd) {
}
WFIFOSET(fd,WFIFOW(fd,2));
-// printf("mmo_char_send006b end..\n");
+
+ #ifdef DEBUG
+ printf("Sent [%d] Chars to [%d]\n",found_num,sd->account_id);
+ #endif
+
return 0;
}
-int parse_tologin(int fd) {
+void reply_login_request(int fd, int len) {
+ if (len < 3)
+ return;
+
+ if (RFIFOB(fd, 2)) {
+ printf("Can not connect to login-server.\n");
+ printf("The server communication passwords (default s1/p1) is probably invalid.\n");
+ printf("Also, please make sure your login db has the username/password present and the sex of the account is S.\n");
+ printf("If you changed the communication passwords, change them back at map_athena.conf and char_athena.conf\n");
+ return;
+ }else {
+ printf("Connected to login-server (connection #%d).\n", fd);
+ // if no map-server already connected, display a message...
+ if(!servers_connected)
+ printf("Awaiting maps from map-server.\n");
+
+ request_gm_accounts();
+
+ // send USER COUNT PING to login server.
+ #ifdef DEBUG
+ printf("Add timer: (send_users_tologin)\n");
+ #endif
+
+ user_count_timer = add_timer_interval(gettick() + 10, send_users_tologin, 0, 0, 5 * 1000);
+ }
+
+ RFIFOSKIP(fd, 3);
+}
+
+void send_chars(int fd, int len) {
+ if(len<51)
+ return;
+
+ int i;
+ struct char_session_data *sd;
+
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
+ if (RFIFOB(fd,6) != 0) {
+ WFIFOW(i,0) = 0x6c;
+ WFIFOB(i,2) = 0x42;
+ WFIFOSET(i,3);
+ } else if (max_connect_user == 0 || count_users() < max_connect_user) {
+ sd->connect_until_time = (time_t)RFIFOL(fd,47);
+ // send characters to player
+ mmo_char_send006b(i, sd);
+ } else {
+ // refuse connection: too much online players
+ WFIFOW(i,0) = 0x6c;
+ WFIFOW(i,2) = 0;
+ WFIFOSET(i,3);
+ }
+ }
+ }
+ RFIFOSKIP(fd,51);
+}
+
+void connect_until_reply(int fd, int len) {
+ if (len < 50)
+ return;
+
int i;
struct char_session_data *sd;
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = session[i]->session_data)) {
+ if (sd->account_id == RFIFOL(fd,2)) {
+ sd->connect_until_time = (time_t)RFIFOL(fd,46);
+ break;
+ }
+ }
+ }
+
+ RFIFOSKIP(fd,50);
+}
+
+// changesex reply (modified by [Yor])
+void change_sex_reply(int fd, int len) {
+ if (len < 7)
+ return;
+
+ int acc, sex, i;
+ unsigned char buf[16];
+ struct char_session_data *sd;
+
+ acc = RFIFOL(fd,2);
+ sex = RFIFOB(fd,6);
+ RFIFOSKIP(fd, 7);
+
+ if (acc > 0) {
+ sprintf(tmp_sql, "SELECT `char_id`,`class`,`skill_point` FROM `%s` WHERE `account_id` = '%d'",char_db, acc);
+ sql_query(tmp_sql,"change_sex_reply");
+
+ if ((sql_res = mysql_store_result(&mysql_handle)) && (sql_row = mysql_fetch_row(sql_res))) {
+ int char_id, jobclass, skill_point, char_class;
+
+ char_id = atoi(sql_row[0]);
+ jobclass = atoi(sql_row[1]);
+ skill_point = atoi(sql_row[2]);
+ char_class = jobclass;
+
+ if (jobclass == 19 || jobclass == 20 ||
+ jobclass == 4020 || jobclass == 4021 ||
+ jobclass == 4042 || jobclass == 4043) {
+
+ // job modification
+ if (jobclass == 19 || jobclass == 20) {
+ char_class = (sex) ? 19 : 20;
+ } else if (jobclass == 4020 || jobclass == 4021) {
+ char_class = (sex) ? 4020 : 4021;
+ } else if (jobclass == 4042 || jobclass == 4043) {
+ char_class = (sex) ? 4042 : 4043;
+ }
+
+ // remove specifical skills of classes 19,20 4020,4021 and 4042,4043
+ sprintf(tmp_sql, "SELECT `lv` FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
+ sql_query(tmp_sql,"change_sex_reply");
+
+ if ((sql_res = mysql_store_result(&mysql_handle))) {
+ while(( sql_row = mysql_fetch_row(sql_res))) {
+ skill_point += atoi(sql_row[0]);
+ }
+ }
+
+ sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
+ sql_query(tmp_sql,"change_sex_reply");
+
+ // to avoid any problem with equipment and invalid sex, equipment is unequiped.
+ sprintf(tmp_sql, "UPDATE `%s` SET `equip` = '0' WHERE `char_id` = '%d'",inventory_db, char_id);
+ sql_query(tmp_sql,"change_sex_reply");
+
+ sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d' , `skill_point`='%d' , `weapon`='0' , `shield='0' , `head_top`='0' , `head_mid`='0' , `head_bottom`='0' WHERE `char_id` = '%d'",char_db, char_class, skill_point, char_id);
+ sql_query(tmp_sql,"change_sex_reply");
+ }
+ }
+
+ // disconnect player if online on char-server
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = session[i]->session_data)) {
+ if (sd->account_id == acc) {
+ session[i]->eof = 1;
+ break;
+ }
+ }
+ }
+
+ WBUFW(buf,0) = 0x2b0d;
+ WBUFL(buf,2) = acc;
+ WBUFB(buf,6) = sex;
+ mapif_sendall(buf, 7);
+ }
+}
+
+void account_reg2(int fd, int len) {
+ if (len < 4 || len < RFIFOW(fd,2))
+ return;
+
+ struct global_reg reg[ACCOUNT_REG2_NUM];
+ unsigned char buf[4096];
+ int j, p, acc;
+
+ acc = RFIFOL(fd,4);
+
+ for(p = 8, j = 0; p < RFIFOW(fd,2) && j < ACCOUNT_REG2_NUM; p += 36, j++) {
+ memcpy(reg[j].str, RFIFOP(fd,p), 32);
+ reg[j].value = RFIFOL(fd,p+32);
+ }
+
+ // set_account_reg2(acc,j,reg);
+ // 同垢ログインを禁止していれば送る必要は無い
+ memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
+ WBUFW(buf,0) = 0x2b11;
+ mapif_sendall(buf, WBUFW(buf,2));
+ RFIFOSKIP(fd, RFIFOW(fd,2));
+
+ #ifdef DEBUG
+ printf("char: save_account_reg_reply\n");
+ #endif
+}
+
+// State change of account/ban notification (from login-server) by [Yor]
+void change_state_reply(int fd, int len) {
+ if (len < 11)
+ return;
+
+ int i;
+ struct char_session_data *sd;
+
+ // send to all map-servers to disconnect the player
+ unsigned char buf[16];
+ WBUFW(buf,0) = 0x2b14;
+ WBUFL(buf,2) = RFIFOL(fd,2);
+ WBUFB(buf,6) = RFIFOB(fd,6); // 0: change of statut, 1: ban
+ WBUFL(buf,7) = RFIFOL(fd,7); // status or final date of a banishment
+ mapif_sendall(buf, 11);
+
+ // disconnect player if online on char-server
+ for(i = 0; i < fd_max; i++) {
+ if (session[i] && (sd = session[i]->session_data)) {
+ if (sd->account_id == RFIFOL(fd,2)) {
+ session[i]->eof = 1;
+ break;
+ }
+ }
+ }
+
+ RFIFOSKIP(fd,11);
+}
+
+int parse_tologin(int fd) {
+ int len = 0;
+
// only login-server can have an access to here.
// so, if it isn't the login-server, we disconnect the session.
//session eof check!
if(fd != login_fd)
session[fd]->eof = 1;
+
if(session[fd]->eof) {
if (fd == login_fd) {
printf("Char-server can't connect to login-server (connection #%d).\n", fd);
@@ -1228,241 +1448,30 @@ int parse_tologin(int fd) {
return 0;
}
- sd = session[fd]->session_data;
-
// hehe. no need to set user limite on SQL version. :P
// but char limitation is good way to maintain server. :D
- while(RFIFOREST(fd) >= 2) {
-// printf("parse_tologin : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
+ len = RFIFOREST(fd);
+ while(len >= 2) {
+ #ifdef DEBUG
+ printf("parse_tologin : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
+ #endif
switch(RFIFOW(fd, 0)){
- case 0x2711:
- if (RFIFOREST(fd) < 3)
- return 0;
- if (RFIFOB(fd, 2)) {
- //printf("connect login server error : %d\n", RFIFOB(fd, 2));
- printf("Can not connect to login-server.\n");
- printf("The server communication passwords (default s1/p1) is probably invalid.\n");
- printf("Also, please make sure your login db has the username/password present and the sex of the account is S.\n");
- printf("If you changed the communication passwords, change them back at map_athena.conf and char_athena.conf\n");
- return 0;
- //exit(1); //fixed for server shutdown.
- }else {
- printf("Connected to login-server (connection #%d).\n", fd);
- // if no map-server already connected, display a message...
- for(i = 0; i < MAX_MAP_SERVERS; i++)
- if (server_fd[i] >= 0 && server[i].map[0][0]) // if map-server online and at least 1 map
- break;
- if (i == MAX_MAP_SERVERS)
- printf("Awaiting maps from map-server.\n");
-
- // send USER COUNT PING to login server.
- printf("add interval tic (send_users_tologin)....\n");
- user_count_timer = add_timer_interval(gettick() + 10, send_users_tologin, 0, 0, 5 * 1000);
- }
- RFIFOSKIP(fd, 3);
- break;
-
- case 0x2713:
- if(RFIFOREST(fd)<51)
- return 0;
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data) && sd->account_id == RFIFOL(fd,2)) {
- if (RFIFOB(fd,6) != 0) {
- WFIFOW(i,0) = 0x6c;
- WFIFOB(i,2) = 0x42;
- WFIFOSET(i,3);
- } else if (max_connect_user == 0 || count_users() < max_connect_user) {
-// if (max_connect_user == 0)
-// printf("max_connect_user (unlimited) -> accepted.\n");
-// else
-// printf("count_users(): %d < max_connect_user (%d) -> accepted.\n", count_users(), max_connect_user);
- sd->connect_until_time = (time_t)RFIFOL(fd,47);
- // send characters to player
- mmo_char_send006b(i, sd);
- } else {
- // refuse connection: too much online players
-// printf("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user);
- WFIFOW(i,0) = 0x6c;
- WFIFOW(i,2) = 0;
- WFIFOSET(i,3);
- }
- }
- }
- RFIFOSKIP(fd,51);
- break;
-
- case 0x2717:
- if (RFIFOREST(fd) < 50)
- return 0;
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
- if (sd->account_id == RFIFOL(fd,2)) {
- sd->connect_until_time = (time_t)RFIFOL(fd,46);
- break;
- }
- }
- }
- RFIFOSKIP(fd,50);
- break;
-
-/* case 0x2721: // gm reply. I don't want to support this function.
- printf("0x2721:GM reply\n");
- {
- int oldacc, newacc;
- unsigned char buf[64];
- if (RFIFOREST(fd) < 10)
- return 0;
- oldacc = RFIFOL(fd, 2);
- newacc = RFIFOL(fd, 6);
- RFIFOSKIP(fd, 10);
- if (newacc > 0) {
- for(i=0;i<char_num;i++){
- if(char_dat[i].account_id==oldacc)
- char_dat[i].account_id=newacc;
- }
- }
- WBUFW(buf,0)=0x2b0b;
- WBUFL(buf,2)=oldacc;
- WBUFL(buf,6)=newacc;
- mapif_sendall(buf,10);
-// printf("char -> map\n");
- }
- break;
-*/
- case 0x2723: // changesex reply (modified by [Yor])
- if (RFIFOREST(fd) < 7)
- return 0;
- {
- int acc, sex;
- unsigned char buf[16];
-
- acc = RFIFOL(fd,2);
- sex = RFIFOB(fd,6);
- RFIFOSKIP(fd, 7);
- if (acc > 0) {
- sprintf(tmp_sql, "SELECT `char_id`,`class`,`skill_point` FROM `%s` WHERE `account_id` = '%d'",char_db, acc);
- 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) {
- int char_id, jobclass, skill_point, class;
- sql_row = mysql_fetch_row(sql_res);
- char_id = atoi(sql_row[0]);
- jobclass = atoi(sql_row[1]);
- skill_point = atoi(sql_row[2]);
- class = jobclass;
- if (jobclass == 19 || jobclass == 20 ||
- jobclass == 4020 || jobclass == 4021 ||
- jobclass == 4042 || jobclass == 4043) {
- // job modification
- if (jobclass == 19 || jobclass == 20) {
- class = (sex) ? 19 : 20;
- } else if (jobclass == 4020 || jobclass == 4021) {
- class = (sex) ? 4020 : 4021;
- } else if (jobclass == 4042 || jobclass == 4043) {
- class = (sex) ? 4042 : 4043;
- }
- // remove specifical skills of classes 19,20 4020,4021 and 4042,4043
- sprintf(tmp_sql, "SELECT `lv` FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
- 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))) {
- skill_point += atoi(sql_row[0]);
- }
- }
- sprintf(tmp_sql, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `id` >= '315' AND `id` <= '330'",skill_db, char_id);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
- }
- }
- // to avoid any problem with equipment and invalid sex, equipment is unequiped.
- sprintf(tmp_sql, "UPDATE `%s` SET `equip` = '0' WHERE `char_id` = '%d'",inventory_db, char_id);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
- }
- sprintf(tmp_sql, "UPDATE `%s` SET `class`='%d' , `skill_point`='%d' , `weapon`='0' , `shield='0' , `head_top`='0' , `head_mid`='0' , `head_bottom`='0' WHERE `char_id` = '%d'",char_db, class, skill_point, char_id);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error (select `char`)- %s\n", mysql_error(&mysql_handle));
- }
- }
- }
- // disconnect player if online on char-server
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
- if (sd->account_id == acc) {
- session[i]->eof = 1;
- break;
- }
- }
- }
-
- WBUFW(buf,0) = 0x2b0d;
- WBUFL(buf,2) = acc;
- WBUFB(buf,6) = sex;
-
- mapif_sendall(buf, 7);
- }
- break;
-
- // account_reg2変更通知
- case 0x2729:
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- {
- struct global_reg reg[ACCOUNT_REG2_NUM];
- unsigned char buf[4096];
- int j, p, acc;
- acc = RFIFOL(fd,4);
- for(p = 8, j = 0; p < RFIFOW(fd,2) && j < ACCOUNT_REG2_NUM; p += 36, j++) {
- memcpy(reg[j].str, RFIFOP(fd,p), 32);
- reg[j].value = RFIFOL(fd,p+32);
- }
- // set_account_reg2(acc,j,reg);
- // 同垢ログインを禁止していれば送る必要は無い
- memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2));
- WBUFW(buf,0) = 0x2b11;
- mapif_sendall(buf, WBUFW(buf,2));
- RFIFOSKIP(fd, RFIFOW(fd,2));
-// printf("char: save_account_reg_reply\n");
- }
- break;
-
- // State change of account/ban notification (from login-server) by [Yor]
- case 0x2731:
- if (RFIFOREST(fd) < 11)
- return 0;
- // send to all map-servers to disconnect the player
- {
- unsigned char buf[16];
- WBUFW(buf,0) = 0x2b14;
- WBUFL(buf,2) = RFIFOL(fd,2);
- WBUFB(buf,6) = RFIFOB(fd,6); // 0: change of statut, 1: ban
- WBUFL(buf,7) = RFIFOL(fd,7); // status or final date of a banishment
- mapif_sendall(buf, 11);
- }
- // disconnect player if online on char-server
- for(i = 0; i < fd_max; i++) {
- if (session[i] && (sd = session[i]->session_data)) {
- if (sd->account_id == RFIFOL(fd,2)) {
- session[i]->eof = 1;
- break;
- }
- }
- }
- RFIFOSKIP(fd,11);
- break;
+ case 0x2711: reply_login_request(fd,len); break;
+ case 0x2713: send_chars(fd,len); break;
+ case 0x2717: connect_until_reply(fd,len); break;
+ case 0x2723: change_sex_reply(fd,len); break;
+ case 0x2729: account_reg2(fd,len); break;
+ case 0x2731: change_state_reply(fd,len); break;
+ case 0x2732: read_gm_accounts(fd,len); break;
default:
printf("set eof.\n");
session[fd]->eof = 1;
return 0;
}
+
+ len = RFIFOREST(fd);
}
RFIFOFLUSH(fd);
@@ -1493,9 +1502,142 @@ int map_anti_freeze_system(int tid, unsigned int tick, int id, int data) {
return 0;
}
+void recv_map_names(int fd, int len, unsigned char id) {
+ if (len < 4 || len < RFIFOW(fd,2))
+ return;
+
+ memset(server[id].map, 0, sizeof(server[id].map));
+
+ int j = 0;
+ unsigned char buf[16384];
+ int x;
+
+ for(i = 4; i < RFIFOW(fd,2); i += 16) {
+ memcpy(server[id].map[j], RFIFOP(fd,i), 16);
+// printf("set map %d.%d : %s\n", id, j, server[id].map[j]);
+ j++;
+ }
+
+ i = server[id].ip;
+
+ unsigned char *p = (unsigned char *)&server[id].ip;
+
+ printf("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
+ id, j, p[0], p[1], p[2], p[3], server[id].port);
+
+
+ WFIFOW(fd,0) = 0x2afb;
+ WFIFOB(fd,2) = 0;
+ memcpy(WFIFOP(fd,3), wisp_server_name, 24); // name for wisp to player
+ WFIFOSET(fd,27);
+
+
+ if (j == 0) {
+ printf("WARNING: Map-Server %d have NO maps.\n", id);
+ } else {
+ // Transmitting maps information to the other map-servers
+ WBUFW(buf,0) = 0x2b04;
+ WBUFW(buf,2) = j * 16 + 10;
+ WBUFL(buf,4) = server[id].ip;
+ WBUFW(buf,8) = server[id].port;
+ memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 16);
+ mapif_sendallwos(fd, buf, WBUFW(buf,2));
+ }
+
+ // Transmitting the maps of the other map-servers to the new map-server
+ for(x = 0; x < MAX_MAP_SERVERS; x++) {
+ if (server_fd[x] >= 0 && x != id) {
+ WFIFOW(fd,0) = 0x2b04;
+ WFIFOL(fd,4) = server[x].ip;
+ WFIFOW(fd,8) = server[x].port;
+
+ j = 0;
+
+ for(i = 0; i < MAX_MAP_PER_SERVER; i++)
+ if (server[x].map[i][0])
+ memcpy(WFIFOP(fd,10+(j++)*16), server[x].map[i], 16);
+
+ if (j > 0) {
+ WFIFOW(fd,2) = j * 16 + 10;
+ WFIFOSET(fd,WFIFOW(fd,2));
+ }
+ }
+ }
+
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+
+ printf("Map-server %d loading complete.\n", id);
+}
+
+void auth_request(int fd, int len) {
+ if (len < 22)
+ return;
+
+ #ifdef DEBUG
+ printf("(AUTH request) auth_fifo search %d %d %d\n", RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
+ #endif
+
+ for(i = 0; i < AUTH_FIFO_SIZE; i++) {
+ if (auth_fifo[i].account_id == RFIFOL(fd,2) &&
+ auth_fifo[i].char_id == RFIFOL(fd,6) &&
+ auth_fifo[i].login_id1 == RFIFOL(fd,10) &&
+#if CMP_AUTHFIFO_LOGIN2 != 0
+ // here, it's the only area where it's possible that we doesn't know login_id2 (map-server asks just after 0x72 packet, that doesn't given the value)
+ (auth_fifo[i].login_id2 == RFIFOL(fd,14) || RFIFOL(fd,14) == 0) && // relate to the versions higher than 18
+#endif
+ (!check_ip_flag || auth_fifo[i].ip == RFIFOL(fd,18)) &&
+ !auth_fifo[i].delflag) {
+
+ auth_fifo[i].delflag = 1;
+ WFIFOW(fd,0) = 0x2afd;
+ WFIFOW(fd,2) = 16 + sizeof(struct mmo_charstatus);
+ WFIFOL(fd,4) = RFIFOL(fd,2);
+ WFIFOL(fd,8) = auth_fifo[i].login_id2;
+ WFIFOL(fd,12) = (unsigned long)auth_fifo[i].connect_until_time;
+ mmo_char_fromsql(auth_fifo[i].char_id, char_dat, 1);
+ char_dat[0].sex = auth_fifo[i].sex;
+ memcpy(WFIFOP(fd,16), &char_dat[0], sizeof(struct mmo_charstatus));
+ WFIFOSET(fd, WFIFOW(fd,2));
+
+ #ifdef DEBUG
+ printf("auth_fifo search success (auth #%d, account %d, character: %d).\n", i, RFIFOL(fd,2), RFIFOL(fd,6));
+ #endif
+
+ return;
+ }
+ }
+
+ if (i == AUTH_FIFO_SIZE) {
+ WFIFOW(fd,0) = 0x2afe;
+ WFIFOL(fd,2) = RFIFOL(fd,2);
+ WFIFOSET(fd,6);
+
+ #ifdef DEBUG
+ printf("(AUTH request) auth_fifo search error!\n");
+ #endif
+ }
+
+ RFIFOSKIP(fd,22);
+}
+
+void set_map_users(int fd, int len) {
+ if (len < 6 || len < RFIFOW(fd,2))
+ return 0;
+
+ if (RFIFOW(fd,4) != server[id].users)
+ printf("map user: %d\n", RFIFOW(fd,4));
+
+ server[id].users = RFIFOW(fd,4);
+
+ if(anti_freeze_enable)
+ server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
+
+ RFIFOSKIP(fd,RFIFOW(fd,2));
+}
+
int parse_frommap(int fd) {
- int i = 0, j = 0;
- int id;
+ int i = 0, j = 0,len;
+ unsigned char id;
// Sometimes fd=0, and it will cause server crash. Don't know why. :(
if (fd <= 0) {
@@ -1503,140 +1645,41 @@ int parse_frommap(int fd) {
return 0;
}
- for(id = 0; id < MAX_MAP_SERVERS; id++)
+ for(id = 0; id < MAX_MAP_SERVERS && id < servers_connected; id++)
if (server_fd[id] == fd)
break;
- if(id == MAX_MAP_SERVERS)
+
+ if(id == MAX_MAP_SERVERS || !servers_connected)
session[fd]->eof = 1;
+
if(session[fd]->eof) {
- if (id < MAX_MAP_SERVERS) {
+ if (servers_connected) {
memset(&server[id], 0, sizeof(struct mmo_map_server));
+
printf("Map-server %d (session #%d) has disconnected.\n", id, fd);
+
sprintf(tmp_sql, "DELETE FROM `ragsrvinfo` WHERE `index`='%d'", server_fd[id]);
- if (mysql_query(&mysql_handle, tmp_sql)) {
- printf("DB server Error - %s\n", mysql_error(&mysql_handle));
- }
+ sql_query(tmp_sql,"parse_frommap");
+
server_fd[id] = -1;
}
close(fd);
delete_session(fd);
return 0;
}
-
- while(RFIFOREST(fd) >= 2) {
-// printf("parse_frommap : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
+
+ len = RFIFOREST(fd);
+
+ while(len >= 2) {
+ #ifdef DEBUG
+ printf("parse_frommap : %d %d %x\n", fd, RFIFOREST(fd), RFIFOW(fd,0));
+ #endif
switch(RFIFOW(fd, 0)) {
- case 0x2af7:
- RFIFOSKIP(fd,2);
- read_gm_account();
- break;
-
- // mapserver -> map names recv.
- case 0x2afa:
- if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- memset(server[id].map, 0, sizeof(server[id].map));
- j = 0;
- for(i = 4; i < RFIFOW(fd,2); i += 16) {
- memcpy(server[id].map[j], RFIFOP(fd,i), 16);
-// printf("set map %d.%d : %s\n", id, j, server[id].map[j]);
- j++;
- }
- i = server[id].ip;
- {
- unsigned char *p = (unsigned char *)&server[id].ip;
- printf("Map-Server %d connected: %d maps, from IP %d.%d.%d.%d port %d.\n",
- id, j, p[0], p[1], p[2], p[3], server[id].port);
- printf("Map-server %d loading complete.\n", id);
- }
- WFIFOW(fd,0) = 0x2afb;
- WFIFOB(fd,2) = 0;
- memcpy(WFIFOP(fd,3), wisp_server_name, 24); // name for wisp to player
- WFIFOSET(fd,27);
- {
- unsigned char buf[16384];
- int x;
- if (j == 0) {
- printf("WARNING: Map-Server %d have NO maps.\n", id);
- // Transmitting maps information to the other map-servers
- } else {
- WBUFW(buf,0) = 0x2b04;
- WBUFW(buf,2) = j * 16 + 10;
- WBUFL(buf,4) = server[id].ip;
- WBUFW(buf,8) = server[id].port;
- memcpy(WBUFP(buf,10), RFIFOP(fd,4), j * 16);
- mapif_sendallwos(fd, buf, WBUFW(buf,2));
- }
- // Transmitting the maps of the other map-servers to the new map-server
- for(x = 0; x < MAX_MAP_SERVERS; x++) {
- if (server_fd[x] >= 0 && x != id) {
- WFIFOW(fd,0) = 0x2b04;
- WFIFOL(fd,4) = server[x].ip;
- WFIFOW(fd,8) = server[x].port;
- j = 0;
- for(i = 0; i < MAX_MAP_PER_SERVER; i++)
- if (server[x].map[i][0])
- memcpy(WFIFOP(fd,10+(j++)*16), server[x].map[i], 16);
- if (j > 0) {
- WFIFOW(fd,2) = j * 16 + 10;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
- }
- }
- }
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
-
- // auth request
- case 0x2afc:
- if (RFIFOREST(fd) < 22)
- return 0;
-// printf("(AUTH request) auth_fifo search %d %d %d\n", RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOL(fd, 10));
- for(i = 0; i < AUTH_FIFO_SIZE; i++) {
- if (auth_fifo[i].account_id == RFIFOL(fd,2) &&
- auth_fifo[i].char_id == RFIFOL(fd,6) &&
- auth_fifo[i].login_id1 == RFIFOL(fd,10) &&
-#if CMP_AUTHFIFO_LOGIN2 != 0
- // here, it's the only area where it's possible that we doesn't know login_id2 (map-server asks just after 0x72 packet, that doesn't given the value)
- (auth_fifo[i].login_id2 == RFIFOL(fd,14) || RFIFOL(fd,14) == 0) && // relate to the versions higher than 18
-#endif
- (!check_ip_flag || auth_fifo[i].ip == RFIFOL(fd,18)) &&
- !auth_fifo[i].delflag) {
- auth_fifo[i].delflag = 1;
- WFIFOW(fd,0) = 0x2afd;
- WFIFOW(fd,2) = 16 + sizeof(struct mmo_charstatus);
- WFIFOL(fd,4) = RFIFOL(fd,2);
- WFIFOL(fd,8) = auth_fifo[i].login_id2;
- WFIFOL(fd,12) = (unsigned long)auth_fifo[i].connect_until_time;
- mmo_char_fromsql(auth_fifo[i].char_id, char_dat, 1);
- char_dat[0].sex = auth_fifo[i].sex;
- memcpy(WFIFOP(fd,16), &char_dat[0], sizeof(struct mmo_charstatus));
- WFIFOSET(fd, WFIFOW(fd,2));
- //printf("auth_fifo search success (auth #%d, account %d, character: %d).\n", i, RFIFOL(fd,2), RFIFOL(fd,6));
- break;
- }
- }
- if (i == AUTH_FIFO_SIZE) {
- WFIFOW(fd,0) = 0x2afe;
- WFIFOL(fd,2) = RFIFOL(fd,2);
- WFIFOSET(fd,6);
-// printf("(AUTH request) auth_fifo search error!\n");
- }
- RFIFOSKIP(fd,22);
- break;
-
- // set MAP user
- case 0x2aff:
- if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
- return 0;
- if (RFIFOW(fd,4) != server[id].users)
- printf("map user: %d\n", RFIFOW(fd,4));
- server[id].users = RFIFOW(fd,4);
- if(anti_freeze_enable)
- server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
- RFIFOSKIP(fd,RFIFOW(fd,2));
- break;
+ case 0x2af7: read_gm_accounts(fd,len); break;
+ case 0x2afa: recv_map_names(fd,len,id); break;
+ case 0x2afc: auth_request(fd,len); break;
+ case 0x2aff: set_map_users(fd,len); break;
// char saving
case 0x2b01:
@@ -1959,6 +2002,8 @@ int parse_frommap(int fd) {
session[fd]->eof = 1;
return 0;
}
+
+ len = RFIFOREST(fd);
}
return 0;
}
diff --git a/src/login_sql/login.c b/src/login_sql/login.c
index b1420cb88..1f123ce91 100644
--- a/src/login_sql/login.c
+++ b/src/login_sql/login.c
@@ -188,22 +188,55 @@ unsigned char isGM(int account_id) {
return *level;
}
-void read_GMs(void) {
+static int gmdb_final(void *key,void *data,va_list ap) {
+ unsigned char *level;
+
+ nullpo_retr(0, level=data);
+
+ free(level);
+
+ return 0;
+}
+
+void do_final_gmdb(void) {
+ if(gm_db){
+ numdb_final(gm_db,gmdb_final);
+ gm_db=NULL;
+ }
+}
+
+void read_GMs(int fd) {
unsigned char *level;
- level = malloc(sizeof(unsigned char));
+ int i=0;
+
+ if(gm_db)
+ do_final_gmdb();
+
+ gm_db = numdb_init();
- sprintf(tmpsql,"SELECT `%s`,`%s` FROM `%s` WHERE `%s` > 0", login_db_account_id, login_db_level, login_db,login_db_level);
+ sprintf(tmpsql,"SELECT `%s`,`%s` FROM `%s` WHERE `%s` > '%d'", login_db_account_id, login_db_level, login_db,login_db_level,lowest_gm_level);
sql_query(tmpsql,"read_GMs");
+ WFIFOW(fd, 0) = 0x2732;
+
if ((sql_res = mysql_store_result(&mysql_handle))) {
- while((sql_row = mysql_fetch_row(sql_res))) {
+ for(i=0;(sql_row = mysql_fetch_row(sql_res));i++) {
+ level = malloc(sizeof(unsigned char));
+
if( (*level = atoi(sql_row[1])) > 99 )
*level = 99;
numdb_insert(gm_db, atoi(sql_row[0]), level);
+
+ WFIFOL(fd,6+5*i) = atoi(sql_row[0]);
+ WFIFOB(fd,10+5*i) = *level;
}
+
+ WFIFOW(fd,2) = i;
}
+ WFIFOSET(fd,6+5*i);
+
mysql_free_result(sql_res);
}
@@ -931,10 +964,6 @@ int do_init(int argc,char **argv){
free(online_db);
online_db = numdb_init();
- // GM database init
- free(gm_db);
- gm_db = numdb_init();
-
// Read GMs from table
read_GMs();