summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/char/char.c31
-rw-r--r--src/char/inter.c1
-rw-r--r--src/common/socket.c9
-rw-r--r--src/common/socket.h2
-rw-r--r--src/config/core.h36
-rw-r--r--src/map/battle.c142
-rw-r--r--src/map/chrif.c16
-rw-r--r--src/map/chrif.h5
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);