diff options
-rw-r--r-- | src/char/char.c | 31 | ||||
-rw-r--r-- | src/char/inter.c | 1 | ||||
-rw-r--r-- | src/common/socket.c | 9 | ||||
-rw-r--r-- | src/common/socket.h | 2 | ||||
-rw-r--r-- | src/config/core.h | 36 | ||||
-rw-r--r-- | src/map/battle.c | 142 | ||||
-rw-r--r-- | src/map/chrif.c | 16 | ||||
-rw-r--r-- | src/map/chrif.h | 5 |
8 files changed, 214 insertions, 28 deletions
diff --git a/src/char/char.c b/src/char/char.c index 0471c91d6..61e0adaf5 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -3285,6 +3285,35 @@ int parse_frommap(int fd) RFIFOSKIP(fd,6); break; + case 0x3008: + if( RFIFOREST(fd) < RFIFOW(fd,4) ) + return 0;/* packet wasn't fully received yet (still fragmented) */ + else { + 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.rathena.org"),(uint16)25421,true) ) == -1 ) { + RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */ + break;/* connection not possible, we drop the report */ + } + + session[sfd]->flag.server = 1;/* to ensure we won't drop our own packet */ + + WFIFOHEAD(sfd, RFIFOW(fd,2) ); + + memcpy((char*)WFIFOP(sfd,0), (char*)RFIFOP(fd, 0), RFIFOW(fd,2)); + + WFIFOSET(sfd, RFIFOW(fd,2) ); + + flush_fifo(sfd); + + do_close(sfd); + + RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */ + } + break; + + default: { // inter server - packet @@ -4244,7 +4273,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data return 0; ShowInfo("Attempt to connect to login-server...\n"); - login_fd = make_connection(login_ip, login_port); + login_fd = make_connection(login_ip, login_port, false); if (login_fd == -1) { //Try again later. [Skotlex] login_fd = 0; diff --git a/src/char/inter.c b/src/char/inter.c index e3fca5e5a..7961b479d 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -1220,6 +1220,7 @@ int inter_parse_frommap(int fd) case 0x3005: mapif_parse_RegistryRequest(fd); break; case 0x3006: mapif_parse_NameChangeRequest(fd); break; case 0x3007: mapif_parse_accinfo(fd); break; + /* 0x3008 is used by the report stuff */ default: if( inter_party_parse_frommap(fd) || inter_guild_parse_frommap(fd) diff --git a/src/common/socket.c b/src/common/socket.c index f8e957788..3d7bb66b4 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -502,8 +502,7 @@ int make_listen_bind(uint32 ip, uint16 port) return fd; } -int make_connection(uint32 ip, uint16 port) -{ +int make_connection(uint32 ip, uint16 port, bool silent) { struct sockaddr_in remote_address; int fd; int result; @@ -533,11 +532,13 @@ int make_connection(uint32 ip, uint16 port) remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_port = htons(port); - ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port); + if( !silent ) + ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { - ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg()); + if( !silent ) + ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg()); do_close(fd); return -1; } diff --git a/src/common/socket.h b/src/common/socket.h index 3c6cebf0b..3265f6487 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -112,7 +112,7 @@ extern bool session_isActive(int fd); // Function prototype declaration int make_listen_bind(uint32 ip, uint16 port); -int make_connection(uint32 ip, uint16 port); +int make_connection(uint32 ip, uint16 port, bool silent); int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size); int realloc_writefifo(int fd, size_t addition); int WFIFOSET(int fd, size_t len); diff --git a/src/config/core.h b/src/config/core.h index fba593dc9..c82ee72e0 100644 --- a/src/config/core.h +++ b/src/config/core.h @@ -8,20 +8,16 @@ * For detailed guidance on these check http://rathena.org/wiki/SRC/config/ **/ -/** - * Max number of items on @autolootid list - **/ +/// Max number of items on @autolootid list #define AUTOLOOTITEM_SIZE 10 -/** - * The maximum number of atcommand suggestions - **/ +/// The maximum number of atcommand suggestions #define MAX_SUGGESTIONS 10 -//Comment to disable the official walk path -// -- The official walkpath disables users from taking non-clear walk paths, -// -- e.g. if they want to get around an obstacle they have to walk around it, -// -- while with OFFICIAL_WALKPATH disabled if they click to walk around a obstacle the server will do it automatically +/// Comment to disable the official walk path +/// The official walkpath disables users from taking non-clear walk paths, +/// e.g. if they want to get around an obstacle they have to walk around it, +/// while with OFFICIAL_WALKPATH disabled if they click to walk around a obstacle the server will do it automatically #define OFFICIAL_WALKPATH /// leave this line uncommented to enable callfunc checks when processing scripts. @@ -31,21 +27,25 @@ /// your map-server using more resources while this is active, comment the line #define SCRIPT_CALLFUNC_CHECK +/// Uncomment to disable rAthena's anonymous stat report +/// We kindly ask you to consider keeping it enabled, it helps us improve rAthena. +//#define STATS_OPT_OUT + /// uncomment to enable query_sql script command and mysql logs to function on it's own thread /// be aware this feature is under tests and you should use at your own risk, we however /// welcome any feedback you may have regarding this feature, please send us all bug reports. //#define BETA_THREAD_TEST -//Uncomment to enable the Cell Stack Limit mod. -//It's only config is the battle_config cell_stack_limit. -//Only chars affected are those defined in BL_CHAR (mobs and players currently) +/// Uncomment to enable the Cell Stack Limit mod. +/// It's only config is the battle_config cell_stack_limit. +/// Only chars affected are those defined in BL_CHAR (mobs and players currently) //#define CELL_NOSTACK -//Uncomment to enable circular area checks. -//By default, all range checks in Aegis are of Square shapes, so a weapon range -// of 10 allows you to attack from anywhere within a 21x21 area. -//Enabling this changes such checks to circular checks, which is more realistic, -// but is not the official behaviour. +/// Uncomment to enable circular area checks. +/// By default, all range checks in Aegis are of Square shapes, so a weapon range +/// - of 10 allows you to attack from anywhere within a 21x21 area. +/// Enabling this changes such checks to circular checks, which is more realistic, +/// - but is not the official behaviour. //#define CIRCULAR_AREA /** diff --git a/src/map/battle.c b/src/map/battle.c index c48f4ce63..b83e2053d 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -8,6 +8,7 @@ #include "../common/showmsg.h" #include "../common/ers.h" #include "../common/random.h" +#include "../common/socket.h" #include "../common/strlib.h" #include "../common/utils.h" @@ -27,6 +28,7 @@ #include "party.h" #include "battle.h" #include "battleground.h" +#include "chrif.h" #include <stdio.h> #include <stdlib.h> @@ -5717,7 +5719,141 @@ static const struct _battle_data { { "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, }, { "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, }, }; +#ifndef STATS_OPT_OUT +/** + * rAthena anonymous statistic usage report -- packet is built here, and sent to char server to report. + **/ +void rAthena_report(char* date, char *time_c) { + int i, rev = 0, bd_size = ARRAYLENGTH(battle_data); + unsigned int config = 0; + const char* rev_str; + char timestring[25]; + time_t curtime; + char* buf; + + enum config_table { + C_CIRCULAR_AREA = 0x0001, + C_CELLNOSTACK = 0x0002, + C_BETA_THREAD_TEST = 0x0004, + C_SCRIPT_CALLFUNC_CHECK = 0x0008, + C_OFFICIAL_WALKPATH = 0x0010, + C_RENEWAL = 0x0020, + C_RENEWAL_CAST = 0x0040, + C_RENEWAL_DROP = 0x0080, + C_RENEWAL_EXP = 0x0100, + C_RENEWAL_LVDMG = 0x0200, + C_RENEWAL_EDP = 0x0400, + C_RENEWAL_ASPD = 0x0800, + C_SECURE_NPCTIMEOUT = 0x1000, + C_SQL_DBS = 0x2000, + C_SQL_LOGS = 0x4000, + }; + + 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 + +#ifdef CELL_NOSTACK + config |= C_CELLNOSTACK; +#endif + +#ifdef BETA_THREAD_TEST + config |= C_BETA_THREAD_TEST; +#endif + +#ifdef SCRIPT_CALLFUNC_CHECK + config |= C_SCRIPT_CALLFUNC_CHECK; +#endif + +#ifdef OFFICIAL_WALKPATH + config |= C_OFFICIAL_WALKPATH; +#endif + +#ifdef RENEWAL + config |= C_RENEWAL; +#endif + +#ifdef RENEWAL_CAST + config |= C_RENEWAL_CAST; +#endif + +#ifdef RENEWAL_DROP + config |= C_RENEWAL_DROP; +#endif + +#ifdef RENEWAL_EXP + config |= C_RENEWAL_EXP; +#endif + +#ifdef RENEWAL_LVDMG + config |= C_RENEWAL_LVDMG; +#endif +#ifdef RENEWAL_EDP + config |= C_RENEWAL_EDP; +#endif + +#ifdef RENEWAL_ASPD + config |= C_RENEWAL_ASPD; +#endif + +/* not a ifdef because SECURE_NPCTIMEOUT is always defined, but either as 0 or higher */ +#if SECURE_NPCTIMEOUT + config |= C_SECURE_NPCTIMEOUT; +#endif + /* non-define part */ + if( db_use_sqldbs ) + config |= C_SQL_DBS; + + if( log_config.sql_logs ) + config |= C_SQL_LOGS; + +#define BFLAG_LENGTH 35 + + CREATE(buf, char, 6 + 12 + 9 + 24 + 4 + 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; + + 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(); + + WBUFL(buf,6 + 12 + 9 + 24 + 4 + 4) = config; + WBUFL(buf,6 + 12 + 9 + 24 + 4 + 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; + } + + chrif_send_report(buf, 6 + 12 + 9 + 24 + 4 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) ); + + aFree(buf); + +#undef BFLAG_LENGTH +} +static int rAthena_report_timer(int tid, unsigned int tick, int id, intptr_t data) { + if( chrif_isconnected() ) {/* char server relays it, so it must be online. */ + rAthena_report(__DATE__,__TIME__); + } + return 0; +} +#endif int battle_set_value(const char* w1, const char* w2) { @@ -5841,6 +5977,12 @@ void do_init_battle(void) { delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR); add_timer_func_list(battle_delay_damage_sub, "battle_delay_damage_sub"); + +#ifndef STATS_OPT_OUT + add_timer_func_list(rAthena_report_timer, "rAthena_report_timer"); + add_timer_interval(gettick()+30000, rAthena_report_timer, 0, 0, 60000 * 30); +#endif + } void do_final_battle(void) diff --git a/src/map/chrif.c b/src/map/chrif.c index 064104018..02bd3686c 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1523,7 +1523,7 @@ static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_ } chrif_state = 0; - char_fd = make_connection(char_ip, char_port); + char_fd = make_connection(char_ip, char_port,false); if (char_fd == -1) { //Attempt to connect later. [Skotlex] return 0; @@ -1562,6 +1562,20 @@ int chrif_removefriend(int char_id, int friend_id) { return 0; } +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. */ +#endif +} + /** * @see DBApply */ diff --git a/src/map/chrif.h b/src/map/chrif.h index dda80cec9..0aadb1a7b 100644 --- a/src/map/chrif.h +++ b/src/map/chrif.h @@ -57,10 +57,9 @@ int chrif_char_online(struct map_session_data *sd); int chrif_changesex(struct map_session_data *sd); int chrif_chardisconnect(struct map_session_data *sd); int chrif_divorce(int partner_id1, int partner_id2); -/** - * rAthena - **/ + int chrif_removefriend(int char_id, int friend_id); +void chrif_send_report(char* buf, int len); int do_final_chrif(void); int do_init_chrif(void); |