From c2d78c0b9e152190d3e1703fce01e02fd7cc6d34 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 1 Apr 2013 22:35:32 -0300 Subject: Introducing socket_datasync a user-friendly way to notify users when their servers are out of sync, e.g. http://hercules.ws/board/topic/328-intif-guild-data-size-error/ http://hercules.ws/board/topic/315-error-chrif-authok-data-size-mismatch-52224-52228/ Signed-off-by: shennetsind --- src/common/socket.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/common/socket.h | 3 +++ 2 files changed, 68 insertions(+), 1 deletion(-) (limited to 'src/common') diff --git a/src/common/socket.c b/src/common/socket.c index 72633cf2b..701fbc685 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -1337,7 +1337,6 @@ void socket_init(void) ShowInfo("Server supports up to '"CL_WHITE"%u"CL_RESET"' concurrent connections.\n", rlim_cur); } - bool session_isValid(int fd) { return ( fd > 0 && fd < FD_SETSIZE && session[fd] != NULL ); @@ -1377,6 +1376,71 @@ uint16 ntows(uint16 netshort) return ((netshort & 0xFF) << 8) | ((netshort & 0xFF00) >> 8); } +/* [Ind/Hercules] - socket_datasync */ +void socket_datasync(int fd, bool send) { + struct { + unsigned int length;/* short is not enough for some */ + } data_list[] = { + { sizeof(struct mmo_charstatus) }, + { sizeof(struct quest) }, + { sizeof(struct item) }, + { sizeof(struct point) }, + { sizeof(struct s_skill) }, + { sizeof(struct global_reg) }, + { sizeof(struct accreg) }, + { sizeof(struct status_change_data) }, + { sizeof(struct storage_data) }, + { sizeof(struct guild_storage) }, + { sizeof(struct s_pet) }, + { sizeof(struct s_mercenary) }, + { sizeof(struct s_homunculus) }, + { sizeof(struct s_elemental) }, + { sizeof(struct s_friend) }, + { sizeof(struct mail_message) }, + { sizeof(struct mail_data) }, + { sizeof(struct registry) }, + { sizeof(struct party_member) }, + { sizeof(struct party) }, + { sizeof(struct guild_member) }, + { sizeof(struct guild_position) }, + { sizeof(struct guild_alliance) }, + { sizeof(struct guild_expulsion) }, + { sizeof(struct guild_skill) }, + { sizeof(struct guild) }, + { sizeof(struct guild_castle) }, + { sizeof(struct fame_list) }, + }; + unsigned short i; + if( send ) { + unsigned short p_len = ( sizeof(data_list) * 4 ) + 4; + WFIFOHEAD(fd, p_len); + + WFIFOW(fd, 0) = 0x2b0a; + WFIFOW(fd, 2) = p_len; + + for( i = 0; i < sizeof(data_list); i++ ) { + WFIFOL(fd, 4 + ( i * 4 ) ) = data_list[i].length; + } + + WFIFOSET(fd, p_len); + } else { + for( i = 0; i < sizeof(data_list); i++ ) { + if( RFIFOL(fd, 4 + (i * 4) ) != data_list[i].length ) { + /* force the other to go wrong too so both are taken down */ + WFIFOHEAD(fd, 8); + WFIFOW(fd, 0) = 0x2b0a; + WFIFOW(fd, 2) = 8; + WFIFOL(fd, 4) = 0; + WFIFOSET(fd, 8); + flush_fifo(fd); + /* shut down */ + ShowFatalError("Servers are out of sync! recompile from scratch\n"); + exit(EXIT_FAILURE); + } + } + } +} + #ifdef SEND_SHORTLIST // Add a fd to the shortlist so that it'll be recognized as a fd that needs // sending or eof handling. diff --git a/src/common/socket.h b/src/common/socket.h index 7c0e02f5d..4879cb109 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -145,6 +145,9 @@ extern int naddr_; // # of ip addresses void set_eof(int fd); +/* [Ind/Hercules] - socket_datasync */ +void socket_datasync(int fd, bool send); + /// Use a shortlist of sockets instead of iterating all sessions for sockets /// that have data to send or need eof handling. /// Adapted to use a static array instead of a linked list. -- cgit v1.2.3-60-g2f50