diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 550 | ||||
-rw-r--r-- | src/common/HPM.c | 2 | ||||
-rw-r--r-- | src/common/grfio.c | 13 | ||||
-rw-r--r-- | src/common/socket.c | 7 | ||||
-rw-r--r-- | src/map/battle.c | 55 | ||||
-rw-r--r-- | src/map/chrif.c | 22 |
6 files changed, 337 insertions, 312 deletions
diff --git a/src/char/char.c b/src/char/char.c index f674cc0c7..ba3179ef9 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2127,304 +2127,302 @@ int parse_fromlogin(int fd) { while(RFIFOREST(fd) >= 2) { uint16 command = RFIFOW(fd,0); + switch( command ) { - switch( command ) - { - - // acknowledgement of connect-to-loginserver request - case 0x2711: - if (RFIFOREST(fd) < 3) - return 0; + // acknowledgement of connect-to-loginserver request + case 0x2711: + if (RFIFOREST(fd) < 3) + return 0; - if (RFIFOB(fd,2)) { - //printf("connect login server error : %d\n", RFIFOB(fd,2)); - ShowError("Can not connect to login-server.\n"); - ShowError("The server communication passwords (default s1/p1) are probably invalid.\n"); - ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n"); - ShowError("The communication passwords are set in /conf/map-server.conf and /conf/char-server.conf\n"); - set_eof(fd); - return 0; - } else { - ShowStatus("Connected to login-server (connection #%d).\n", fd); - loginif_on_ready(); - } - RFIFOSKIP(fd,3); - break; + if (RFIFOB(fd,2)) { + //printf("connect login server error : %d\n", RFIFOB(fd,2)); + ShowError("Can not connect to login-server.\n"); + ShowError("The server communication passwords (default s1/p1) are probably invalid.\n"); + ShowError("Also, please make sure your login db has the correct communication username/passwords and the gender of the account is S.\n"); + ShowError("The communication passwords are set in /conf/map-server.conf and /conf/char-server.conf\n"); + set_eof(fd); + return 0; + } else { + ShowStatus("Connected to login-server (connection #%d).\n", fd); + loginif_on_ready(); + } + RFIFOSKIP(fd,3); + break; - // acknowledgement of account authentication request - case 0x2713: - if (RFIFOREST(fd) < 25) - return 0; - { - int account_id = RFIFOL(fd,2); - uint32 login_id1 = RFIFOL(fd,6); - uint32 login_id2 = RFIFOL(fd,10); - uint8 sex = RFIFOB(fd,14); - uint8 result = RFIFOB(fd,15); - int request_id = RFIFOL(fd,16); - uint32 version = RFIFOL(fd,20); - uint8 clienttype = RFIFOB(fd,24); - RFIFOSKIP(fd,25); - - if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) && - !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex ) + // acknowledgement of account authentication request + case 0x2713: + if (RFIFOREST(fd) < 25) + return 0; { - int client_fd = request_id; - sd->version = version; - sd->clienttype = clienttype; - switch( result ) + int account_id = RFIFOL(fd,2); + uint32 login_id1 = RFIFOL(fd,6); + uint32 login_id2 = RFIFOL(fd,10); + uint8 sex = RFIFOB(fd,14); + uint8 result = RFIFOB(fd,15); + int request_id = RFIFOL(fd,16); + uint32 version = RFIFOL(fd,20); + uint8 clienttype = RFIFOB(fd,24); + RFIFOSKIP(fd,25); + + if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) && + !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex ) { - case 0:// ok - char_auth_ok(client_fd, sd); - break; - case 1:// auth failed - WFIFOHEAD(client_fd,3); - WFIFOW(client_fd,0) = 0x6c; - WFIFOB(client_fd,2) = 0;// rejected from server - WFIFOSET(client_fd,3); - break; + int client_fd = request_id; + sd->version = version; + sd->clienttype = clienttype; + switch( result ) + { + case 0:// ok + char_auth_ok(client_fd, sd); + break; + case 1:// auth failed + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; + } } } - } - break; + break; - case 0x2717: // account data - if (RFIFOREST(fd) < 72) - return 0; + case 0x2717: // account data + if (RFIFOREST(fd) < 72) + return 0; - // find the authenticated session with this account id - ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) ); - if( i < fd_max ) { - int server_id; - memcpy(sd->email, RFIFOP(fd,6), 40); - sd->expiration_time = (time_t)RFIFOL(fd,46); - sd->group_id = RFIFOB(fd,50); - sd->char_slots = RFIFOB(fd,51); - if( sd->char_slots > MAX_CHARS ) { - ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.h! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots); - sd->char_slots = MAX_CHARS;/* cap to maximum */ - } else if ( sd->char_slots <= 0 )/* no value aka 0 in sql */ - sd->char_slots = MAX_CHARS;/* cap to maximum */ - safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate)); - safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode)); - sd->pincode_change = RFIFOL(fd,68); - ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] ); - // continued from char_auth_ok... - if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359 - (max_connect_user == 0 && sd->group_id != gm_allow_group) || - ( max_connect_user > 0 && count_users() >= max_connect_user && sd->group_id != gm_allow_group ) ) { - // refuse connection (over populated) - WFIFOHEAD(i,3); - WFIFOW(i,0) = 0x6c; - WFIFOW(i,2) = 0; - WFIFOSET(i,3); - } else { - // send characters to player -#if PACKETVER >= 20130000 - mmo_char_send082d(i, sd); -#else - mmo_char_send006b(i, sd); -#endif -#if PACKETVER >= 20110309 - pincode->handle(i, sd); -#endif + // find the authenticated session with this account id + ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) ); + if( i < fd_max ) { + int server_id; + memcpy(sd->email, RFIFOP(fd,6), 40); + sd->expiration_time = (time_t)RFIFOL(fd,46); + sd->group_id = RFIFOB(fd,50); + sd->char_slots = RFIFOB(fd,51); + if( sd->char_slots > MAX_CHARS ) { + ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.h! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots); + sd->char_slots = MAX_CHARS;/* cap to maximum */ + } else if ( sd->char_slots <= 0 )/* no value aka 0 in sql */ + sd->char_slots = MAX_CHARS;/* cap to maximum */ + safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate)); + safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode)); + sd->pincode_change = RFIFOL(fd,68); + ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] ); + // continued from char_auth_ok... + if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359 + (max_connect_user == 0 && sd->group_id != gm_allow_group) || + ( max_connect_user > 0 && count_users() >= max_connect_user && sd->group_id != gm_allow_group ) ) { + // refuse connection (over populated) + WFIFOHEAD(i,3); + WFIFOW(i,0) = 0x6c; + WFIFOW(i,2) = 0; + WFIFOSET(i,3); + } else { + // send characters to player + #if PACKETVER >= 20130000 + mmo_char_send082d(i, sd); + #else + mmo_char_send006b(i, sd); + #endif + #if PACKETVER >= 20110309 + pincode->handle(i, sd); + #endif + } } - } - RFIFOSKIP(fd,72); - break; + RFIFOSKIP(fd,72); + break; - // login-server alive packet - case 0x2718: - if (RFIFOREST(fd) < 2) - return 0; - RFIFOSKIP(fd,2); - session[fd]->flag.ping = 0; - break; + // login-server alive packet + case 0x2718: + if (RFIFOREST(fd) < 2) + return 0; + RFIFOSKIP(fd,2); + session[fd]->flag.ping = 0; + break; - // changesex reply - case 0x2723: - if (RFIFOREST(fd) < 7) - return 0; - { - unsigned char buf[7]; - - int acc = RFIFOL(fd,2); - int sex = RFIFOB(fd,6); - RFIFOSKIP(fd,7); - - if( acc > 0 ) - {// TODO: Is this even possible? - int char_id[MAX_CHARS]; - int class_[MAX_CHARS]; - int guild_id[MAX_CHARS]; - int num; - char* data; + // changesex reply + case 0x2723: + if (RFIFOREST(fd) < 7) + return 0; + { + unsigned char buf[7]; + + int acc = RFIFOL(fd,2); + int sex = RFIFOB(fd,6); + RFIFOSKIP(fd,7); + + if( acc > 0 ) + {// TODO: Is this even possible? + int char_id[MAX_CHARS]; + int class_[MAX_CHARS]; + int guild_id[MAX_CHARS]; + int num; + char* data; - struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); - if( node != NULL ) - node->sex = sex; + struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); + if( node != NULL ) + node->sex = sex; - // get characters - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) ) - Sql_ShowDebug(sql_handle); - for( i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i ) - { - Sql_GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data); - } - num = i; - for( i = 0; i < num; ++i ) - { - if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER || - class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY || - class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER || - class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER || - class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T || - class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER || - class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO ) + // get characters + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) ) + Sql_ShowDebug(sql_handle); + for( i = 0; i < MAX_CHARS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i ) { - // job modification - if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ) - class_[i] = (sex ? JOB_BARD : JOB_DANCER); - else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ) - class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY); - else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ) - class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER); - else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ) - class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER); - else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ) - class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T); - else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ) - class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER); - else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO ) - class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO); + Sql_GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data); + Sql_GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data); + Sql_GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data); } + num = i; + for( i = 0; i < num; ++i ) + { + if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER || + class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY || + class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER || + class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER || + class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T || + class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER || + class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO ) + { + // job modification + if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ) + class_[i] = (sex ? JOB_BARD : JOB_DANCER); + else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ) + class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY); + else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ) + class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER); + else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ) + class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER); + else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ) + class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T); + else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ) + class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER); + else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO ) + class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO); + } - if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]) ) - Sql_ShowDebug(sql_handle); + if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]) ) + Sql_ShowDebug(sql_handle); + + if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex] + inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex); + } + Sql_FreeResult(sql_handle); - if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex] - inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex); + // disconnect player if online on char-server + disconnect_player(acc); } - Sql_FreeResult(sql_handle); - // disconnect player if online on char-server - disconnect_player(acc); + // notify all mapservers about this change + WBUFW(buf,0) = 0x2b0d; + WBUFL(buf,2) = acc; + WBUFB(buf,6) = sex; + mapif_sendall(buf, 7); } + break; - // notify all mapservers about this change - WBUFW(buf,0) = 0x2b0d; - WBUFL(buf,2) = acc; - WBUFB(buf,6) = sex; - mapif_sendall(buf, 7); - } - break; - - // reply to an account_reg2 registry request - case 0x2729: - if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) - return 0; + // reply to an account_reg2 registry request + case 0x2729: + if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) + return 0; - { //Receive account_reg2 registry, forward to map servers. - unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)]; - memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2)); - WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex] - mapif_sendall(buf, WBUFW(buf,2)); - RFIFOSKIP(fd, RFIFOW(fd,2)); - } - break; + { //Receive account_reg2 registry, forward to map servers. + unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)]; + memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2)); + WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex] + mapif_sendall(buf, WBUFW(buf,2)); + RFIFOSKIP(fd, RFIFOW(fd,2)); + } + break; - // State change of account/ban notification (from login-server) - case 0x2731: - if (RFIFOREST(fd) < 11) - return 0; + // State change of account/ban notification (from login-server) + case 0x2731: + if (RFIFOREST(fd) < 11) + return 0; - { // send to all map-servers to disconnect the player - unsigned char buf[11]; - 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 - disconnect_player(RFIFOL(fd,2)); + { // send to all map-servers to disconnect the player + unsigned char buf[11]; + 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 + disconnect_player(RFIFOL(fd,2)); - RFIFOSKIP(fd,11); - break; + RFIFOSKIP(fd,11); + break; - // Login server request to kick a character out. [Skotlex] - case 0x2734: - if (RFIFOREST(fd) < 6) - return 0; - { - int aid = RFIFOL(fd,2); - struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid); - RFIFOSKIP(fd,6); - if( character != NULL ) - {// account is already marked as online! - if( character->server > -1 ) - { //Kick it from the map server it is on. - mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2); - if (character->waiting_disconnect == INVALID_TIMER) - character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0); - } - else - {// Manual kick from char server. - struct char_session_data *tsd; - int i; - ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid ); - if( i < fd_max ) - { - WFIFOHEAD(i,3); - WFIFOW(i,0) = 0x81; - WFIFOB(i,2) = 2; // "Someone has already logged in with this id" - WFIFOSET(i,3); - set_eof(i); + // Login server request to kick a character out. [Skotlex] + case 0x2734: + if (RFIFOREST(fd) < 6) + return 0; + { + int aid = RFIFOL(fd,2); + struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid); + RFIFOSKIP(fd,6); + if( character != NULL ) + {// account is already marked as online! + if( character->server > -1 ) + { //Kick it from the map server it is on. + mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2); + if (character->waiting_disconnect == INVALID_TIMER) + character->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, chardb_waiting_disconnect, character->account_id, 0); + } + else + {// Manual kick from char server. + struct char_session_data *tsd; + int i; + ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid ); + if( i < fd_max ) + { + WFIFOHEAD(i,3); + WFIFOW(i,0) = 0x81; + WFIFOB(i,2) = 2; // "Someone has already logged in with this id" + WFIFOSET(i,3); + set_eof(i); + } + else // still moving to the map-server + set_char_offline(-1, aid); } - else // still moving to the map-server - set_char_offline(-1, aid); } + idb_remove(auth_db, aid);// reject auth attempts from map-server } - idb_remove(auth_db, aid);// reject auth attempts from map-server - } - break; + break; - // ip address update signal from login server - case 0x2735: - { - unsigned char buf[2]; - uint32 new_ip = 0; - - WBUFW(buf,0) = 0x2b1e; - mapif_sendall(buf, 2); - - new_ip = host2ip(login_ip_str); - if (new_ip && new_ip != login_ip) - login_ip = new_ip; //Update login ip, too. - - new_ip = host2ip(char_ip_str); - if (new_ip && new_ip != char_ip) - { //Update ip. - char_ip = new_ip; - ShowInfo("Updating IP for [%s].\n", char_ip_str); - // notify login server about the change - WFIFOHEAD(fd,6); - WFIFOW(fd,0) = 0x2736; - WFIFOL(fd,2) = htonl(char_ip); - WFIFOSET(fd,6); - } + // ip address update signal from login server + case 0x2735: + { + unsigned char buf[2]; + uint32 new_ip = 0; + + WBUFW(buf,0) = 0x2b1e; + mapif_sendall(buf, 2); + + new_ip = host2ip(login_ip_str); + if (new_ip && new_ip != login_ip) + login_ip = new_ip; //Update login ip, too. + + new_ip = host2ip(char_ip_str); + if (new_ip && new_ip != char_ip) + { //Update ip. + char_ip = new_ip; + ShowInfo("Updating IP for [%s].\n", char_ip_str); + // notify login server about the change + WFIFOHEAD(fd,6); + WFIFOW(fd,0) = 0x2736; + WFIFOL(fd,2) = htonl(char_ip); + WFIFOSET(fd,6); + } - RFIFOSKIP(fd,2); - } - break; + RFIFOSKIP(fd,2); + } + break; - default: - ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command); - set_eof(fd); - return 0; - } + default: + ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command); + set_eof(fd); + return 0; + } } RFIFOFLUSH(fd); @@ -2670,14 +2668,12 @@ int parse_frommap(int fd) int id; ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd ); - if( id == ARRAYLENGTH(server) ) - {// not a map server + if( id == ARRAYLENGTH(server) ) {// not a map server ShowDebug("parse_frommap: Disconnecting invalid session #%d (is not a map-server)\n", fd); do_close(fd); return 0; } - if( session[fd]->flag.eof ) - { + if( session[fd]->flag.eof ) { do_close(fd); server[id].fd = -1; mapif_on_disconnect(id); @@ -2685,7 +2681,6 @@ int parse_frommap(int fd) } while(RFIFOREST(fd) >= 2) { - switch(RFIFOW(fd,0)) { case 0x2b0a: @@ -3299,6 +3294,7 @@ int parse_frommap(int fd) WFIFOW(fd,0) = 0x2b24; WFIFOSET(fd,2); RFIFOSKIP(fd,2); + ShowDebug("Received 2b23, sending 2b24\n"); break; case 0x2b26: // auth request from map-server @@ -3381,16 +3377,18 @@ int parse_frommap(int fd) if( RFIFOREST(fd) < RFIFOW(fd,4) ) return 0;/* packet wasn't fully received yet (still fragmented) */ else { - int sfd;/* stat server fd */ + int sfd;/* stat server fd */ RFIFOSKIP(fd, 2);/* we skip first 2 bytes which are the 0x3008, so we end up with a buffer equal to the one we send */ - if( (sfd = make_connection(host2ip("stats.hercules.ws"),(uint16)25421,true) ) == -1 ) { + if( (sfd = make_connection(host2ip("stats.hercules.ws"),(uint16)25427,true) ) == -1 ) { RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */ + RFIFOFLUSH(fd); break;/* connection not possible, we drop the report */ } - + session[sfd]->flag.server = 1;/* to ensure we won't drop our own packet */ - + realloc_fifo(sfd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); + WFIFOHEAD(sfd, RFIFOW(fd,2) ); memcpy((char*)WFIFOP(sfd,0), (char*)RFIFOP(fd, 0), RFIFOW(fd,2)); @@ -3400,8 +3398,9 @@ int parse_frommap(int fd) flush_fifo(sfd); do_close(sfd); - + RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */ + RFIFOFLUSH(fd); } break; @@ -3728,6 +3727,7 @@ int parse_char(int fd) #define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } } cmd = RFIFOW(fd,0); + switch( cmd ) { // request to connect diff --git a/src/common/HPM.c b/src/common/HPM.c index 4802fbc61..2df559c82 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -53,7 +53,7 @@ bool hplugin_iscompatible(char* version) { if( version == NULL ) return false; - sscanf(version, "%d.%d", &req_major, &req_minor); + sscanf(version, "%u.%u", &req_major, &req_minor); return ( req_major == HPM->version[0] && req_minor <= HPM->version[1] ) ? true : false; } diff --git a/src/common/grfio.c b/src/common/grfio.c index cc2f866f7..bf66dba52 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/des.h" @@ -250,8 +251,12 @@ int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned /// zlib compress -int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen) -{ +int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen) { + if( *destLen == 0 ) /* [Ind/Hercules] */ + *destLen = compressBound(sourceLen); + if( dest == NULL ) { /* [Ind/Hercules] */ + CREATE(dest, unsigned char, *destLen); + } return compress((Bytef*)dest, destLen, (const Bytef*)source, sourceLen); } diff --git a/src/common/socket.c b/src/common/socket.c index 79ccdf5dc..5126d231b 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/mmo.h" @@ -812,7 +813,7 @@ int do_sockets(int next) continue; // after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed) - if (session[i]->rdata_size == RFIFO_SIZE && session[i]->max_rdata == RFIFO_SIZE) { + if (session[i]->rdata_size == session[i]->max_rdata) { set_eof(i); continue; } diff --git a/src/map/battle.c b/src/map/battle.c index ed0b87e6f..796938926 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -5940,9 +5940,10 @@ static const struct _battle_data { * Hercules anonymous statistic usage report -- packet is built here, and sent to char server to report. **/ void Hercules_report(char* date, char *time_c) { - int i, rev = 0, bd_size = ARRAYLENGTH(battle_data); + int i, bd_size = ARRAYLENGTH(battle_data); unsigned int config = 0; - const char* rev_str; + const char *svn = get_svn_revision(); + const char *git = get_git_hash(); char timestring[25]; time_t curtime; char* buf; @@ -5950,7 +5951,7 @@ void Hercules_report(char* date, char *time_c) { enum config_table { C_CIRCULAR_AREA = 0x0001, C_CELLNOSTACK = 0x0002, - //C_BETA_THREAD_TEST = 0x0004, (free slot) + C_CONSOLE_INPUT = 0x0004, C_SCRIPT_CALLFUNC_CHECK = 0x0008, C_OFFICIAL_WALKPATH = 0x0010, C_RENEWAL = 0x0020, @@ -5963,16 +5964,16 @@ void Hercules_report(char* date, char *time_c) { C_SECURE_NPCTIMEOUT = 0x1000, C_SQL_DBS = 0x2000, C_SQL_LOGS = 0x4000, + C_MEMWATCH = 0x8000, + C_DMALLOC = 0x10000, + C_GCOLLECT = 0x20000, + C_SEND_SHORTLIST = 0x40000, }; - if( (rev_str = get_svn_revision()) != 0 ) - rev = atoi(rev_str); - /* we get the current time */ time(&curtime); strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", localtime(&curtime)); - - + #ifdef CIRCULAR_AREA config |= C_CIRCULAR_AREA; #endif @@ -5981,6 +5982,10 @@ void Hercules_report(char* date, char *time_c) { config |= C_CELLNOSTACK; #endif +#ifdef CONSOLE_INPUT + config |= C_CONSOLE_INPUT; +#endif + #ifdef SCRIPT_CALLFUNC_CHECK config |= C_SCRIPT_CALLFUNC_CHECK; #endif @@ -6028,32 +6033,46 @@ void Hercules_report(char* date, char *time_c) { if( logs->config.sql_logs ) config |= C_SQL_LOGS; +#ifdef MEMWATCH + config |= C_MEMWATCH; +#endif +#ifdef DMALLOC + config |= C_DMALLOC; +#endif +#ifdef GCOLLECT + config |= C_GCOLLECT; +#endif + +#ifdef SEND_SHORTLIST + config |= C_SEND_SHORTLIST; +#endif + #define BFLAG_LENGTH 35 - CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 ); + CREATE(buf, char, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 ); /* build packet */ WBUFW(buf,0) = 0x3000; - WBUFW(buf,2) = 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ); - WBUFW(buf,4) = 0x9c; + WBUFW(buf,2) = 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ); + WBUFW(buf,4) = 0x9e; safestrncpy((char*)WBUFP(buf,6), date, 12); safestrncpy((char*)WBUFP(buf,6 + 12), time_c, 9); safestrncpy((char*)WBUFP(buf,6 + 12 + 9), timestring, 24); - WBUFL(buf,6 + 12 + 9 + 24) = rev; - WBUFL(buf,6 + 12 + 9 + 24 + 4) = map_getusers(); + safestrncpy((char*)WBUFP(buf,6 + 12 + 9 + 24), git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown", 41); + WBUFL(buf,6 + 12 + 9 + 24 + 41) = map_getusers(); - WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4) = config; - WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4) = bd_size; + WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4) = config; + WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4) = bd_size; for( i = 0; i < bd_size; i++ ) { - safestrncpy((char*)WBUFP(buf,6 + 12 + 9+ 24 + 4 + 4 + 4 + 4 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, 35); - WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val; + safestrncpy((char*)WBUFP(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, 35); + WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val; } - chrif_send_report(buf, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) ); + chrif_send_report(buf, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) ); aFree(buf); diff --git a/src/map/chrif.c b/src/map/chrif.c index cf7886422..69fc79bb8 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1577,19 +1577,19 @@ int chrif_removefriend(int char_id, int friend_id) { } void chrif_send_report(char* buf, int len) { - #ifndef STATS_OPT_OUT - WFIFOHEAD(char_fd,len + 2); - - WFIFOW(char_fd,0) = 0x3008; - - memcpy(WFIFOP(char_fd,2), buf, len); - - WFIFOSET(char_fd,len + 2); - - flush_fifo(char_fd); /* ensure it's sent now. */ + if( char_fd ) { + WFIFOHEAD(char_fd,len + 2); + + WFIFOW(char_fd,0) = 0x3008; + + memcpy(WFIFOP(char_fd,2), buf, len); + + WFIFOSET(char_fd,len + 2); + + flush_fifo(char_fd); /* ensure it's sent now. */ + } #endif - } /** |