* Made a crazy attempt to at least partially synchronize login&char code
* Major edit to the way the servers handle ip addresses, making them obey the "host byte order inside, network byte order outside" rule - hopefully covered all entry- and exit-points for IP address data - discovered several places where Gravity's client breaks the convention, will need to come up with a suitable countermeasure for that - other than that, the code should be portable, except for printing and ipban mask testing (those still assume a specific byte order) - tested both txt and sql in all usual situations; tested single- and multi-server setups, all seems to work (but watch out for hidden bugs!) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10162 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
dd818415a1
commit
8dc1b77f03
@ -3,6 +3,17 @@ Date Added
|
||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2007/04/06
|
||||
* Made a crazy attempt to at least partially synchronize login&char code
|
||||
* Major edit to the way the servers handle ip addresses, making them obey
|
||||
the "host byte order inside, network byte order outside" rule [ultramage]
|
||||
- hopefully covered all entry- and exit-points for IP address data
|
||||
- discovered several places where Gravity's client breaks the convention,
|
||||
will need to come up with a suitable countermeasure for that
|
||||
- other than that, the code should be portable, except for printing and
|
||||
ipban mask testing (those still assume a specific byte order)
|
||||
- tested both txt and sql in all usual situations; tested single- and
|
||||
multi-server setups, all seems to work (but watch out for hidden bugs!)
|
||||
2007/04/05
|
||||
* Cleaned @whogm. It will display the name of all gms online. If their GM
|
||||
level is above your own, it will only display their name, otherwise level,
|
||||
|
422
src/char/char.c
422
src/char/char.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -215,8 +215,8 @@ struct mmo_charstatus {
|
||||
short str,agi,vit,int_,dex,luk;
|
||||
unsigned char char_num,sex;
|
||||
|
||||
unsigned long mapip;
|
||||
unsigned int mapport;
|
||||
uint32 mapip;
|
||||
uint16 mapport;
|
||||
|
||||
struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
|
||||
struct item inventory[MAX_INVENTORY],cart[MAX_CART];
|
||||
|
@ -242,7 +242,7 @@ int connect_client(int listen_fd)
|
||||
|
||||
len = sizeof(client_address);
|
||||
|
||||
fd = accept(listen_fd,(struct sockaddr*)&client_address,&len);
|
||||
fd = accept(listen_fd, (struct sockaddr*)&client_address, &len);
|
||||
if ( fd == INVALID_SOCKET ) {
|
||||
ShowError("accept failed (code %i)!\n", s_errno);
|
||||
return -1;
|
||||
@ -258,7 +258,7 @@ int connect_client(int listen_fd)
|
||||
set_nonblocking(fd, 1);
|
||||
|
||||
#ifndef MINICORE
|
||||
if( ip_rules && !connect_check(*(uint32*)(&client_address.sin_addr)) ){
|
||||
if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) {
|
||||
do_close(fd);
|
||||
return -1;
|
||||
}
|
||||
@ -270,13 +270,13 @@ int connect_client(int listen_fd)
|
||||
fd_max = fd + 1;
|
||||
|
||||
create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
|
||||
session[fd]->client_addr = client_address;
|
||||
session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
|
||||
session[fd]->rdata_tick = last_tick;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int make_listen_bind(long ip,int port)
|
||||
int make_listen_bind(uint32 ip, uint16 port)
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
int fd;
|
||||
@ -293,8 +293,8 @@ int make_listen_bind(long ip,int port)
|
||||
set_nonblocking(fd, 1);
|
||||
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = ip;
|
||||
server_address.sin_port = htons((unsigned short)port);
|
||||
server_address.sin_addr.s_addr = htonl(ip);
|
||||
server_address.sin_port = htons(port);
|
||||
|
||||
result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
|
||||
if( result == SOCKET_ERROR ) {
|
||||
@ -320,7 +320,7 @@ int make_listen_bind(long ip,int port)
|
||||
return fd;
|
||||
}
|
||||
|
||||
int make_connection(long ip, int port)
|
||||
int make_connection(uint32 ip, uint16 port)
|
||||
{
|
||||
struct sockaddr_in server_address;
|
||||
int fd;
|
||||
@ -335,12 +335,11 @@ int make_connection(long ip, int port)
|
||||
|
||||
setsocketopts(fd);
|
||||
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = ip;
|
||||
server_address.sin_port = htons((unsigned short)port);
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = htonl(ip);
|
||||
server_address.sin_port = htons(port);
|
||||
|
||||
ShowStatus("Connecting to %d.%d.%d.%d:%i\n",
|
||||
(ip)&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,(ip>>24)&0xFF,port);
|
||||
ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port);
|
||||
|
||||
result = connect(fd, (struct sockaddr *)(&server_address), sizeof(struct sockaddr_in));
|
||||
if( result == SOCKET_ERROR ) {
|
||||
@ -389,7 +388,7 @@ int delete_session(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size)
|
||||
int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
|
||||
{
|
||||
if( !session_isValid(fd) )
|
||||
return 0;
|
||||
@ -421,7 +420,7 @@ int realloc_writefifo(int fd, size_t addition)
|
||||
else if( session[fd]->max_wdata >= FIFOSIZE_SERVERLINK) {
|
||||
//Inter-server adjust. [Skotlex]
|
||||
if ((session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata)
|
||||
newsize = session[fd]->max_wdata/2;
|
||||
newsize = session[fd]->max_wdata / 2;
|
||||
else
|
||||
return 0; //No change
|
||||
} else if( session[fd]->max_wdata > wfifo_size && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata )
|
||||
@ -437,7 +436,7 @@ int realloc_writefifo(int fd, size_t addition)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RFIFOSKIP(int fd,int len)
|
||||
int RFIFOSKIP(int fd, int len)
|
||||
{
|
||||
struct socket_data *s;
|
||||
|
||||
@ -468,11 +467,10 @@ int WFIFOSET(int fd, int len)
|
||||
// we have written len bytes to the buffer already before calling WFIFOSET
|
||||
if(s->wdata_size+len > s->max_wdata)
|
||||
{ // actually there was a buffer overflow already
|
||||
unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
|
||||
ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n", fd,
|
||||
sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3], len, s->wdata_size, s->max_wdata);
|
||||
ShowDebug("Likely command that caused it: 0x%x\n",
|
||||
(*(unsigned short*)(s->wdata + s->wdata_size)));
|
||||
uint32 ip = s->client_addr;
|
||||
ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n",
|
||||
fd, CONVIP(ip), len, s->wdata_size, s->max_wdata);
|
||||
ShowDebug("Likely command that caused it: 0x%x\n", (*(unsigned short*)(s->wdata + s->wdata_size)));
|
||||
// no other chance, make a better fifo model
|
||||
exit(1);
|
||||
}
|
||||
@ -645,15 +643,13 @@ static int access_order = ACO_DENY_ALLOW;
|
||||
static int access_allownum = 0;
|
||||
static int access_denynum = 0;
|
||||
static int access_debug = 0;
|
||||
static int ddos_count = 10;
|
||||
static int ddos_interval = 3*1000;
|
||||
static int ddos_autoreset = 10*60*1000;
|
||||
static int ddos_count = 10;
|
||||
static int ddos_interval = 3*1000;
|
||||
static int ddos_autoreset = 10*60*1000;
|
||||
/// Connection history, an array of linked lists.
|
||||
/// The array's index for any ip is ip&0xFFFF
|
||||
static ConnectHistory* connect_history[0x10000];
|
||||
|
||||
#define CONVIP(ip) ip&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,ip>>24
|
||||
|
||||
static int connect_check_(uint32 ip);
|
||||
|
||||
/// Verifies if the IP can connect. (with debug info)
|
||||
@ -816,7 +812,7 @@ int access_ipmask(const char* str, AccessControl* acc)
|
||||
unsigned int m[4];
|
||||
int n;
|
||||
|
||||
if( strcmp(str,"all") == 0 ){
|
||||
if( strcmp(str,"all") == 0 ) {
|
||||
ip = 0;
|
||||
mask = 0;
|
||||
} else {
|
||||
@ -856,7 +852,7 @@ int access_ipmask(const char* str, AccessControl* acc)
|
||||
#endif
|
||||
//////////////////////////////
|
||||
|
||||
int socket_config_read(const char *cfgName)
|
||||
int socket_config_read(const char* cfgName)
|
||||
{
|
||||
char line[1024],w1[1024],w2[1024];
|
||||
FILE *fp;
|
||||
@ -960,7 +956,7 @@ void do_close(int fd)
|
||||
|
||||
/// Retrieve local ips in host byte order.
|
||||
/// Uses loopback is no address is found.
|
||||
int socket_getips(uint32 *ips, int max)
|
||||
int socket_getips(uint32* ips, int max)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
@ -986,7 +982,7 @@ int socket_getips(uint32 *ips, int max)
|
||||
{
|
||||
hent = gethostbyname(fullhost);
|
||||
if( hent == NULL ){
|
||||
ShowError("socket_getips: Cannot resolve our own hostname to a IP address\n");
|
||||
ShowError("socket_getips: Cannot resolve our own hostname to an IP address\n");
|
||||
return 0;
|
||||
}
|
||||
a = (u_long**)hent->h_addr_list;
|
||||
@ -1099,16 +1095,18 @@ int session_isActive(int fd)
|
||||
return ( session_isValid(fd) && !session[fd]->eof );
|
||||
}
|
||||
|
||||
|
||||
in_addr_t host2ip(const char* hostname)
|
||||
// Resolves hostname into a numeric ip.
|
||||
uint32 host2ip(const char* hostname)
|
||||
{
|
||||
struct hostent* h = gethostbyname(hostname);
|
||||
return (h != NULL) ? *(in_addr_t*)h->h_addr : 0;
|
||||
return (h != NULL) ? ntohl(*(uint32*)h->h_addr) : 0;
|
||||
}
|
||||
|
||||
const char* ip2str(in_addr_t ip, char ip_str[16])
|
||||
// Converts a numeric ip into a dot-formatted string.
|
||||
// Result is placed either into a user-provided buffer or a static system buffer.
|
||||
const char* ip2str(uint32 ip, char ip_str[16])
|
||||
{
|
||||
in_addr_t addr = ntohl(ip);
|
||||
sprintf(ip_str, "%d.%d.%d.%d", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF);
|
||||
return ip_str;
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(ip);
|
||||
return (ip_str == NULL) ? inet_ntoa(addr) : strncpy(ip_str, inet_ntoa(addr), 16);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ struct socket_data {
|
||||
size_t rdata_size, wdata_size;
|
||||
size_t rdata_pos;
|
||||
time_t rdata_tick; // time of last receive (for detecting timeouts)
|
||||
struct sockaddr_in client_addr; // remote client address (zero for s2s connections)
|
||||
uint32 client_addr; // remote client address (zero for s2s connections)
|
||||
void* session_data;
|
||||
RecvFunc func_recv;
|
||||
SendFunc func_send;
|
||||
@ -106,12 +106,12 @@ extern int session_isActive(int fd);
|
||||
|
||||
// Function prototype declaration
|
||||
|
||||
int make_listen_bind(long,int);
|
||||
int make_connection(long,int);
|
||||
int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size);
|
||||
int make_listen_bind(uint32 ip, uint16 port);
|
||||
int make_connection(uint32 ip, uint16 port);
|
||||
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,int len);
|
||||
int RFIFOSKIP(int fd,int len);
|
||||
int WFIFOSET(int fd, int len);
|
||||
int RFIFOSKIP(int fd, int len);
|
||||
|
||||
int do_sendrecv(int next);
|
||||
int do_parsepacket(void);
|
||||
@ -126,9 +126,9 @@ extern void set_nonblocking(int fd, int yes);
|
||||
void set_defaultparse(ParseFunc defaultparse);
|
||||
|
||||
// hostname/ip conversion functions
|
||||
in_addr_t host2ip(const char* hostname);
|
||||
const char* ip2str(in_addr_t ip, char ip_str[16]);
|
||||
|
||||
uint32 host2ip(const char* hostname);
|
||||
const char* ip2str(uint32 ip, char ip_str[16]);
|
||||
#define CONVIP(ip) (ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,(ip>>0)&0xFF
|
||||
|
||||
int socket_getips(uint32* ips, int max);
|
||||
|
||||
|
@ -11,12 +11,15 @@
|
||||
#include "../common/utils.h"
|
||||
#include "../common/malloc.h"
|
||||
|
||||
//-----------------------------------------------
|
||||
// string lib.
|
||||
char* jstrescape (char* pt) {
|
||||
|
||||
#define J_MAX_MALLOC_SIZE 65535
|
||||
|
||||
// escapes a string in-place (' -> \' , \ -> \\ , % -> _)
|
||||
char* jstrescape (char* pt)
|
||||
{
|
||||
//copy from here
|
||||
char *ptr;
|
||||
int i =0, j=0;
|
||||
int i = 0, j = 0;
|
||||
|
||||
//copy string to temporary
|
||||
CREATE(ptr, char, J_MAX_MALLOC_SIZE);
|
||||
@ -41,10 +44,12 @@ char* jstrescape (char* pt) {
|
||||
}
|
||||
pt[j++] = '\0';
|
||||
aFree(ptr);
|
||||
return &pt[0];
|
||||
return pt;
|
||||
}
|
||||
|
||||
char* jstrescapecpy (char* pt, const char* spt) {
|
||||
// escapes a string into a provided buffer
|
||||
char* jstrescapecpy (char* pt, const char* spt)
|
||||
{
|
||||
//copy from here
|
||||
//WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
|
||||
//a escape character is found, the target's final length increases! [Skotlex]
|
||||
@ -75,7 +80,10 @@ char* jstrescapecpy (char* pt, const char* spt) {
|
||||
pt[j++] = '\0';
|
||||
return &pt[0];
|
||||
}
|
||||
int jmemescapecpy (char* pt,char* spt, int size) {
|
||||
|
||||
// escapes exactly 'size' bytes of a string into a provided buffer
|
||||
int jmemescapecpy (char* pt, const char* spt, int size)
|
||||
{
|
||||
//copy from here
|
||||
int i =0, j=0;
|
||||
|
||||
@ -100,11 +108,9 @@ int jmemescapecpy (char* pt,char* spt, int size) {
|
||||
return j;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Function to suppress control characters in a string.
|
||||
//-----------------------------------------------------
|
||||
//int remove_control_chars(char *str) {
|
||||
int remove_control_chars(unsigned char *str) {
|
||||
int remove_control_chars(char* str)
|
||||
{
|
||||
int i;
|
||||
int change = 0;
|
||||
|
||||
@ -119,11 +125,11 @@ int remove_control_chars(unsigned char *str) {
|
||||
}
|
||||
|
||||
//Trims a string, also removes illegal characters such as \t and reduces continous spaces to a single one. by [Foruken]
|
||||
char *trim(char *str, const char *delim)
|
||||
char* trim(char* str, const char* delim)
|
||||
{
|
||||
char *strp = strtok(str,delim);
|
||||
char* strp = strtok(str,delim);
|
||||
char buf[1024];
|
||||
char *bufp = buf;
|
||||
char* bufp = buf;
|
||||
memset(buf,0,sizeof buf);
|
||||
|
||||
while(strp) {
|
||||
@ -143,7 +149,7 @@ char *trim(char *str, const char *delim)
|
||||
//stristr: Case insensitive version of strstr, code taken from
|
||||
//http://www.daniweb.com/code/snippet313.html, Dave Sinkula
|
||||
//
|
||||
const char *stristr(const char *haystack, const char *needle)
|
||||
const char* stristr(const char* haystack, const char* needle)
|
||||
{
|
||||
if ( !*needle )
|
||||
{
|
||||
@ -153,9 +159,7 @@ const char *stristr(const char *haystack, const char *needle)
|
||||
{
|
||||
if ( TOUPPER(*haystack) == TOUPPER(*needle) )
|
||||
{
|
||||
/*
|
||||
* Matched starting char -- loop through remaining chars.
|
||||
*/
|
||||
// matched starting char -- loop through remaining chars
|
||||
const char *h, *n;
|
||||
for ( h = haystack, n = needle; *h && *n; ++h, ++n )
|
||||
{
|
||||
@ -164,9 +168,9 @@ const char *stristr(const char *haystack, const char *needle)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !*n ) /* matched all of 'needle' to null termination */
|
||||
if ( !*n ) // matched all of 'needle' to null termination
|
||||
{
|
||||
return haystack; /* return the start of the match */
|
||||
return haystack; // return the start of the match
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,7 +178,7 @@ const char *stristr(const char *haystack, const char *needle)
|
||||
}
|
||||
|
||||
#ifdef __WIN32
|
||||
char *_strtok_r(char *s1, const char *s2, char **lasts)
|
||||
char* _strtok_r(char *s1, const char *s2, char **lasts)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
|
@ -4,25 +4,20 @@
|
||||
#ifndef _STRLIB_H_
|
||||
#define _STRLIB_H_
|
||||
|
||||
#define J_MAX_MALLOC_SIZE 65535
|
||||
// String function library.
|
||||
// code by Jioh L. Jung (ziozzang@4wish.net)
|
||||
// This code is under license "BSD"
|
||||
char* jstrescape (char* pt);
|
||||
char* jstrescapecpy (char* pt, const char* spt);
|
||||
int jmemescapecpy (char* pt,char* spt, int size);
|
||||
int jmemescapecpy (char* pt, const char* spt, int size);
|
||||
|
||||
int remove_control_chars(char *);
|
||||
char *trim(char *str, const char *delim);
|
||||
const char *stristr(const char *haystack, const char *needle);
|
||||
|
||||
#ifdef __WIN32
|
||||
#define HAVE_STRTOK_R
|
||||
#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
|
||||
char *_strtok_r(char *s1, const char *s2, char **lasts);
|
||||
char* _strtok_r(char* s1, const char* s2, char** lasts);
|
||||
#endif
|
||||
|
||||
// custom functions
|
||||
int remove_control_chars(unsigned char *);
|
||||
char *trim(char *str, const char *delim);
|
||||
const char *stristr(const char *haystack, const char *needle);
|
||||
|
||||
#if !defined(WIN32) || (defined(_MSC_VER) && _MSC_VER < 1400)
|
||||
size_t strnlen (const char* string, size_t maxlen);
|
||||
#endif
|
||||
|
@ -20,28 +20,28 @@
|
||||
#include "../common/showmsg.h"
|
||||
#include "../common/cbasetypes.h"
|
||||
|
||||
void dump(unsigned char *buffer, int num)
|
||||
void dump(unsigned char* buffer, int num)
|
||||
{
|
||||
int icnt,jcnt;
|
||||
int icnt, jcnt;
|
||||
|
||||
printf(" Hex ASCII\n");
|
||||
printf(" ----------------------------------------------- ----------------");
|
||||
|
||||
for (icnt=0;icnt<num;icnt+=16) {
|
||||
printf("\n%p ",&buffer[icnt]);
|
||||
for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
|
||||
for (icnt = 0; icnt < num; icnt += 16) {
|
||||
printf("\n%p ", &buffer[icnt]);
|
||||
for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
|
||||
if (jcnt < num) {
|
||||
printf("%02hX ",buffer[jcnt]);
|
||||
printf("%02hX ", buffer[jcnt]);
|
||||
} else
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
printf(" | ");
|
||||
|
||||
for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
|
||||
for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
|
||||
if (jcnt < num) {
|
||||
if (buffer[jcnt] > 31 && buffer[jcnt] < 127)
|
||||
printf("%c",buffer[jcnt]);
|
||||
printf("%c", buffer[jcnt]);
|
||||
else
|
||||
printf(".");
|
||||
} else
|
||||
@ -266,30 +266,20 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
|
||||
|
||||
unsigned char GetByte(unsigned long val, size_t num)
|
||||
{
|
||||
switch(num)
|
||||
{
|
||||
case 0:
|
||||
return (unsigned char)((val & 0x000000FF) );
|
||||
case 1:
|
||||
return (unsigned char)((val & 0x0000FF00)>>0x08);
|
||||
case 2:
|
||||
return (unsigned char)((val & 0x00FF0000)>>0x10);
|
||||
case 3:
|
||||
return (unsigned char)((val & 0xFF000000)>>0x18);
|
||||
default:
|
||||
return 0; //better throw something here
|
||||
switch(num) {
|
||||
case 0: return (unsigned char)((val & 0x000000FF) );
|
||||
case 1: return (unsigned char)((val & 0x0000FF00)>>0x08);
|
||||
case 2: return (unsigned char)((val & 0x00FF0000)>>0x10);
|
||||
case 3: return (unsigned char)((val & 0xFF000000)>>0x18);
|
||||
default: return 0; //better throw something here
|
||||
}
|
||||
}
|
||||
unsigned short GetWord(unsigned long val, size_t num)
|
||||
{
|
||||
switch(num)
|
||||
{
|
||||
case 0:
|
||||
return (unsigned short)((val & 0x0000FFFF) );
|
||||
case 1:
|
||||
return (unsigned short)((val & 0xFFFF0000)>>0x10);
|
||||
default:
|
||||
return 0; //better throw something here
|
||||
switch(num) {
|
||||
case 0: return (unsigned short)((val & 0x0000FFFF) );
|
||||
case 1: return (unsigned short)((val & 0xFFFF0000)>>0x10);
|
||||
default: return 0; //better throw something here
|
||||
}
|
||||
}
|
||||
unsigned short MakeWord(unsigned char byte0, unsigned char byte1)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,7 +40,7 @@
|
||||
|
||||
struct Login_Config {
|
||||
|
||||
in_addr_t login_ip; // the address to bind to
|
||||
uint32 login_ip; // the address to bind to
|
||||
unsigned short login_port; // the port to bind to
|
||||
bool log_login; // whether to log login server actions or not
|
||||
char date_format[32]; // date format used in messages
|
||||
@ -71,17 +71,17 @@ struct mmo_char_server server[MAX_SERVERS]; // char server data
|
||||
|
||||
// Advanced subnet check [LuzZza]
|
||||
struct _subnet {
|
||||
long subnet;
|
||||
long mask;
|
||||
long char_ip;
|
||||
long map_ip;
|
||||
uint32 subnet;
|
||||
uint32 mask;
|
||||
uint32 char_ip;
|
||||
uint32 map_ip;
|
||||
} subnet[16];
|
||||
|
||||
int subnet_count = 0;
|
||||
|
||||
|
||||
struct gm_account* gm_account_db = NULL;
|
||||
int GM_num = 0; // number of gm accounts
|
||||
unsigned int GM_num = 0; // number of gm accounts
|
||||
|
||||
//Account registration flood protection [Kevin]
|
||||
int allowed_regs = 1;
|
||||
@ -118,7 +118,9 @@ char login_db_level[256] = "level";
|
||||
#define AUTH_FIFO_SIZE 256
|
||||
struct {
|
||||
int account_id,login_id1,login_id2;
|
||||
int ip,sex,delflag;
|
||||
uint32 ip;
|
||||
char sex;
|
||||
bool delflag;
|
||||
} auth_fifo[AUTH_FIFO_SIZE];
|
||||
|
||||
int auth_fifo_pos = 0;
|
||||
@ -235,12 +237,13 @@ void read_gm_account(void)
|
||||
//-----------------------------------------------------
|
||||
void send_GM_accounts(int fd)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
unsigned char buf[32767];
|
||||
int len;
|
||||
|
||||
if(!login_config.login_gm_read)
|
||||
return;
|
||||
|
||||
len = 4;
|
||||
WBUFW(buf,0) = 0x2732;
|
||||
for(i = 0; i < GM_num; i++)
|
||||
@ -254,16 +257,17 @@ void send_GM_accounts(int fd)
|
||||
break;
|
||||
}
|
||||
}
|
||||
WBUFW(buf,2) = len;
|
||||
if (fd == -1)
|
||||
charif_sendallwos(-1, buf, len);
|
||||
else
|
||||
{
|
||||
WFIFOHEAD(fd, len);
|
||||
memcpy(WFIFOP(fd,0), buf, len);
|
||||
WFIFOSET(fd, len);
|
||||
}
|
||||
return;
|
||||
|
||||
WBUFW(buf,2) = len;
|
||||
if (fd == -1)
|
||||
charif_sendallwos(-1, buf, len);
|
||||
else
|
||||
{
|
||||
WFIFOHEAD(fd, len);
|
||||
memcpy(WFIFOP(fd,0), buf, len);
|
||||
WFIFOSET(fd, len);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
@ -497,20 +501,20 @@ int mmo_auth_new(struct mmo_account* account, char sex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send to char
|
||||
//--------------------------------------------------------------------
|
||||
// Packet send to all char-servers, except one (wos: without our self)
|
||||
//--------------------------------------------------------------------
|
||||
int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
|
||||
{
|
||||
int i, c;
|
||||
int fd;
|
||||
int i, c, fd;
|
||||
|
||||
c = 0;
|
||||
for(i = 0; i < MAX_SERVERS; i++) {
|
||||
for(i = 0, c = 0; i < MAX_SERVERS; i++) {
|
||||
if ((fd = server_fd[i]) > 0 && fd != sfd) {
|
||||
WFIFOHEAD(fd,len);
|
||||
WFIFOHEAD(fd, len);
|
||||
if (WFIFOSPACE(fd) < len) //Increase buffer size.
|
||||
realloc_writefifo(fd, len);
|
||||
memcpy(WFIFOP(fd,0), buf, len);
|
||||
WFIFOSET(fd,len);
|
||||
WFIFOSET(fd, len);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
@ -532,8 +536,9 @@ int mmo_auth(struct mmo_account* account, int fd)
|
||||
char md5str[64], md5bin[32];
|
||||
|
||||
char ip[16];
|
||||
unsigned char* sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr.s_addr;
|
||||
sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
|
||||
uint32 ipl = session[fd]->client_addr;
|
||||
uint8* sin_addr = (uint8*)&ipl;
|
||||
sprintf(ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
|
||||
|
||||
// DNS Blacklist check
|
||||
if(login_config.use_dnsbl)
|
||||
@ -543,7 +548,7 @@ int mmo_auth(struct mmo_account* account, int fd)
|
||||
char *dnsbl_serv;
|
||||
bool matched = false;
|
||||
|
||||
sprintf(r_ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
|
||||
sprintf(r_ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
|
||||
|
||||
for (dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,","))
|
||||
{
|
||||
@ -720,9 +725,9 @@ int mmo_auth(struct mmo_account* account, int fd)
|
||||
|
||||
if (login_config.online_check) {
|
||||
struct online_login_data* data = idb_get(online_db,account->account_id);
|
||||
unsigned char buf[8];
|
||||
if (data && data->char_server > -1) {
|
||||
//Request char servers to kick this account out. [Skotlex]
|
||||
unsigned char buf[8];
|
||||
ShowNotice("User [%s] is already online - Rejected.\n",account->userid);
|
||||
WBUFW(buf,0) = 0x2734;
|
||||
WBUFL(buf,2) = account->account_id;
|
||||
@ -764,19 +769,18 @@ static int online_db_setoffline(DBKey key, void* data, va_list ap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// char-server packet parse
|
||||
//-----------------------------------------------------
|
||||
//--------------------------------
|
||||
// Packet parsing for char-servers
|
||||
//--------------------------------
|
||||
int parse_fromchar(int fd)
|
||||
{
|
||||
int i, id;
|
||||
|
||||
unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
|
||||
unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
|
||||
uint32 ipl = session[fd]->client_addr;
|
||||
char ip[16];
|
||||
RFIFOHEAD(fd);
|
||||
|
||||
sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
ip2str(ipl, ip);
|
||||
|
||||
for(id = 0; id < MAX_SERVERS; id++)
|
||||
if (server_fd[id] == fd)
|
||||
@ -802,14 +806,14 @@ int parse_fromchar(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(RFIFOREST(fd) >= 2) {
|
||||
// printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
|
||||
while (RFIFOREST(fd) >= 2) {
|
||||
|
||||
switch (RFIFOW(fd,0)) {
|
||||
case 0x2709:
|
||||
|
||||
case 0x2709: // request from map-server via char-server to reload GM accounts
|
||||
if (login_config.log_login)
|
||||
{
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, (unsigned int)ntohl(ipl),server[id].name);
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, ipl, server[id].name);
|
||||
if (mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
@ -821,7 +825,7 @@ int parse_fromchar(int fd)
|
||||
RFIFOSKIP(fd,2);
|
||||
break;
|
||||
|
||||
case 0x2712:
|
||||
case 0x2712: // request from char-server to authenticate an account
|
||||
if (RFIFOREST(fd) < 19)
|
||||
return 0;
|
||||
{
|
||||
@ -833,7 +837,7 @@ int parse_fromchar(int fd)
|
||||
auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
|
||||
auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
|
||||
auth_fifo[i].sex == RFIFOB(fd,14) &&
|
||||
auth_fifo[i].ip == RFIFOL(fd,15) &&
|
||||
auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
|
||||
!auth_fifo[i].delflag)
|
||||
{
|
||||
auth_fifo[i].delflag = 1;
|
||||
@ -869,9 +873,10 @@ int parse_fromchar(int fd)
|
||||
WFIFOB(fd,6) = 1;
|
||||
WFIFOSET(fd,51);
|
||||
}
|
||||
}
|
||||
RFIFOSKIP(fd,19);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 0x2714:
|
||||
if (RFIFOREST(fd) < 6)
|
||||
@ -897,8 +902,7 @@ int parse_fromchar(int fd)
|
||||
RFIFOSKIP(fd,6);
|
||||
break;
|
||||
|
||||
// We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server
|
||||
case 0x2716:
|
||||
case 0x2716: // received an e-mail/limited time request, because a player comes back from a map-server to the char-server
|
||||
if (RFIFOREST(fd) < 6)
|
||||
return 0;
|
||||
{
|
||||
@ -929,10 +933,8 @@ int parse_fromchar(int fd)
|
||||
RFIFOSKIP(fd,6);
|
||||
break;
|
||||
|
||||
case 0x2720: // GM
|
||||
if (RFIFOREST(fd) < 4)
|
||||
return 0;
|
||||
if (RFIFOREST(fd) < RFIFOW(fd,2))
|
||||
case 0x2720: // Request to become a GM (TXT only!)
|
||||
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
|
||||
return 0;
|
||||
//oldacc = RFIFOL(fd,4);
|
||||
ShowWarning("change GM isn't supported in this login server version.\n");
|
||||
@ -995,7 +997,7 @@ int parse_fromchar(int fd)
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x2724: // Receiving of map-server via char-server a status change resquest (by Yor)
|
||||
case 0x2724: // Receiving of map-server via char-server a status change resquest
|
||||
if (RFIFOREST(fd) < 10)
|
||||
return 0;
|
||||
{
|
||||
@ -1029,7 +1031,7 @@ int parse_fromchar(int fd)
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor)
|
||||
case 0x2725: // Receiving of map-server via char-server a ban resquest
|
||||
if (RFIFOREST(fd) < 18)
|
||||
return 0;
|
||||
{
|
||||
@ -1084,7 +1086,7 @@ int parse_fromchar(int fd)
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x2727:
|
||||
case 0x2727: // Change of sex (sex is reversed)
|
||||
if (RFIFOREST(fd) < 6)
|
||||
return 0;
|
||||
{
|
||||
@ -1168,10 +1170,9 @@ int parse_fromchar(int fd)
|
||||
if (buf) aFree(buf);
|
||||
}
|
||||
RFIFOSKIP(fd,RFIFOW(fd,2));
|
||||
//printf("login: save account_reg (from char)\n");
|
||||
break;
|
||||
|
||||
case 0x272a: // Receiving of map-server via char-server a unban resquest (by Yor)
|
||||
case 0x272a: // Receiving of map-server via char-server a unban resquest
|
||||
if (RFIFOREST(fd) < 6)
|
||||
return 0;
|
||||
{
|
||||
@ -1209,6 +1210,7 @@ int parse_fromchar(int fd)
|
||||
remove_online_user(RFIFOL(fd,2));
|
||||
RFIFOSKIP(fd,6);
|
||||
break;
|
||||
|
||||
case 0x272d: // Receive list of all online accounts. [Skotlex]
|
||||
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
|
||||
return 0;
|
||||
@ -1270,10 +1272,8 @@ int parse_fromchar(int fd)
|
||||
case 0x2736: // WAN IP update from char-server
|
||||
if (RFIFOREST(fd) < 6)
|
||||
return 0;
|
||||
ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id,
|
||||
(int)RFIFOB(fd,2),(int)RFIFOB(fd,3),
|
||||
(int)RFIFOB(fd,4),(int)RFIFOB(fd,5));
|
||||
server[id].ip = RFIFOL(fd,2);
|
||||
server[id].ip = ntohl(RFIFOL(fd,2));
|
||||
ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
|
||||
RFIFOSKIP(fd,6);
|
||||
break;
|
||||
|
||||
@ -1284,7 +1284,7 @@ int parse_fromchar(int fd)
|
||||
break;
|
||||
|
||||
default:
|
||||
ShowError("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
|
||||
ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", RFIFOW(fd,0));
|
||||
session[fd]->eof = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -1297,12 +1297,12 @@ int parse_fromchar(int fd)
|
||||
//--------------------------------------------
|
||||
// Test to know if an IP come from LAN or WAN.
|
||||
//--------------------------------------------
|
||||
int lan_subnetcheck(long p)
|
||||
int lan_subnetcheck(uint32 ip)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<subnet_count; i++) {
|
||||
if(subnet[i].subnet == (p & subnet[i].mask)) {
|
||||
for(i = 0; i < subnet_count; i++) {
|
||||
if(subnet[i].subnet == (ip & subnet[i].mask)) {
|
||||
return subnet[i].char_ip;
|
||||
}
|
||||
}
|
||||
@ -1310,14 +1310,11 @@ int lan_subnetcheck(long p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int login_ip_ban_check(unsigned char *p, unsigned long ipl)
|
||||
int login_ip_ban_check(uint32 ip)
|
||||
{
|
||||
//ip ban
|
||||
//p[0], p[1], p[2], p[3]
|
||||
//request DB connection
|
||||
//check
|
||||
char* p = (char*)&ip;
|
||||
sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
|
||||
p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
|
||||
p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]);
|
||||
if (mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
@ -1338,11 +1335,11 @@ int login_ip_ban_check(unsigned char *p, unsigned long ipl)
|
||||
}
|
||||
|
||||
// ip ban ok.
|
||||
ShowInfo("Packet from banned ip : %d.%d.%d.%d\n" RETCODE, p[0], p[1], p[2], p[3]);
|
||||
ShowInfo("Packet from banned ip : %d.%d.%d.%d\n" RETCODE, CONVIP(ip));
|
||||
|
||||
if (login_config.log_login)
|
||||
{
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', 'unknown','-3', 'ip banned')", loginlog_db, (unsigned int)ntohl(ipl));
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', 'unknown','-3', 'ip banned')", loginlog_db, ip);
|
||||
// query
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
@ -1360,16 +1357,13 @@ int parse_login(int fd)
|
||||
{
|
||||
char t_uid[100];
|
||||
struct mmo_account account;
|
||||
long subnet_char_ip;
|
||||
int packet_len;
|
||||
|
||||
int result, i;
|
||||
unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
|
||||
unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
|
||||
uint32 ipl = session[fd]->client_addr;
|
||||
char ip[16];
|
||||
RFIFOHEAD(fd);
|
||||
|
||||
sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
ip2str(ipl, ip);
|
||||
|
||||
memset(&account, 0, sizeof(account));
|
||||
|
||||
@ -1381,9 +1375,9 @@ int parse_login(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(RFIFOREST(fd)>=2 && !session[fd]->eof){
|
||||
while(RFIFOREST(fd) >= 2) {
|
||||
|
||||
switch(RFIFOW(fd,0)){
|
||||
switch(RFIFOW(fd,0)) {
|
||||
case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
|
||||
if (RFIFOREST(fd) < 26)
|
||||
return 0;
|
||||
@ -1399,18 +1393,22 @@ int parse_login(int fd)
|
||||
case 0x277: // New login packet
|
||||
case 0x64: // request client login
|
||||
case 0x01dd: // request client login with encrypt
|
||||
{
|
||||
int packet_len = RFIFOREST(fd);
|
||||
|
||||
packet_len = RFIFOREST(fd);
|
||||
|
||||
//Perform ip-ban check ONLY on login packets
|
||||
if (login_config.ipban && login_ip_ban_check(p,ipl))
|
||||
//Perform ip-ban check
|
||||
if (login_config.ipban && login_ip_ban_check(ipl))
|
||||
{
|
||||
WFIFOHEAD(fd, 23);
|
||||
WFIFOW(fd,0) = 0x6a;
|
||||
WFIFOB(fd,2) = 3; // 3 = Rejected from Server
|
||||
WFIFOSET(fd,23);
|
||||
RFIFOSKIP(fd,packet_len);
|
||||
session[fd]->eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(RFIFOW(fd,0)){
|
||||
switch(RFIFOW(fd, 0)){
|
||||
case 0x64:
|
||||
if(packet_len < 55)
|
||||
return 0;
|
||||
@ -1432,7 +1430,6 @@ int parse_login(int fd)
|
||||
memcpy(account.passwd,RFIFOP(fd, 30),NAME_LENGTH);
|
||||
account.passwd[23] = '\0';
|
||||
|
||||
// ShowDebug("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
|
||||
#ifdef PASSWORDENC
|
||||
account.passwdenc= (RFIFOW(fd,0)!=0x01dd)?0:PASSWORDENC;
|
||||
#else
|
||||
@ -1441,7 +1438,7 @@ int parse_login(int fd)
|
||||
result=mmo_auth(&account, fd);
|
||||
|
||||
jstrescapecpy(t_uid,account.userid);
|
||||
if(result==-1){
|
||||
if(result==-1) { // auth success
|
||||
if (login_config.min_level_to_connect > account.level) {
|
||||
WFIFOHEAD(fd,3);
|
||||
WFIFOW(fd,0) = 0x81;
|
||||
@ -1449,8 +1446,8 @@ int parse_login(int fd)
|
||||
WFIFOSET(fd,3);
|
||||
} else {
|
||||
WFIFOHEAD(fd,47+32*MAX_SERVERS);
|
||||
if (p[0] != 127 && login_config.log_login) {
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, (unsigned int)ntohl(ipl), t_uid);
|
||||
if (login_config.log_login) {
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, ipl, t_uid);
|
||||
//query
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
@ -1461,15 +1458,14 @@ int parse_login(int fd)
|
||||
ShowStatus("Connection of the GM (level:%d) account '%s' accepted.\n", account.level, account.userid);
|
||||
else
|
||||
ShowStatus("Connection of the account '%s' accepted.\n", account.userid);
|
||||
server_num=0;
|
||||
|
||||
server_num = 0;
|
||||
for(i = 0; i < MAX_SERVERS; i++) {
|
||||
if (server_fd[i] >= 0) {
|
||||
// Advanced subnet check [LuzZza]
|
||||
if((subnet_char_ip = lan_subnetcheck(ipl)))
|
||||
WFIFOL(fd,47+server_num*32) = subnet_char_ip;
|
||||
else
|
||||
WFIFOL(fd,47+server_num*32) = server[i].ip;
|
||||
WFIFOW(fd,47+server_num*32+4) = server[i].port;
|
||||
uint32 subnet_char_ip = lan_subnetcheck(ipl);
|
||||
WFIFOL(fd,47+server_num*32) = (subnet_char_ip) ? htonl(subnet_char_ip) : htonl(server[i].ip);
|
||||
WFIFOW(fd,47+server_num*32+4) = server[i].port; // /!\ must be sent in intel host byte order /!\ (client bug)
|
||||
memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
|
||||
WFIFOW(fd,47+server_num*32+26) = server[i].users;
|
||||
WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
|
||||
@ -1477,34 +1473,33 @@ int parse_login(int fd)
|
||||
server_num++;
|
||||
}
|
||||
}
|
||||
// if at least 1 char-server
|
||||
if (server_num > 0) {
|
||||
WFIFOW(fd,0)=0x69;
|
||||
WFIFOW(fd,2)=47+32*server_num;
|
||||
WFIFOL(fd,4)=account.login_id1;
|
||||
WFIFOL(fd,8)=account.account_id;
|
||||
WFIFOL(fd,12)=account.login_id2;
|
||||
WFIFOL(fd,16)=0;
|
||||
//memcpy(WFIFOP(fd,20),account.lastlogin,24);
|
||||
WFIFOB(fd,46)=account.sex;
|
||||
if (server_num > 0) { // if at least 1 char-server
|
||||
WFIFOW(fd,0) = 0x69;
|
||||
WFIFOW(fd,2) = 47+32*server_num;
|
||||
WFIFOL(fd,4) = account.login_id1;
|
||||
WFIFOL(fd,8) = account.account_id;
|
||||
WFIFOL(fd,12) = account.login_id2;
|
||||
WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
|
||||
//memcpy(WFIFOP(fd,20), account.lastlogin, 24); // in old version, that was for name (not more used)
|
||||
WFIFOB(fd,46) = account.sex;
|
||||
WFIFOSET(fd,47+32*server_num);
|
||||
if(auth_fifo_pos>=AUTH_FIFO_SIZE)
|
||||
auth_fifo_pos=0;
|
||||
auth_fifo[auth_fifo_pos].account_id=account.account_id;
|
||||
auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
|
||||
auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
|
||||
auth_fifo[auth_fifo_pos].sex=account.sex;
|
||||
auth_fifo[auth_fifo_pos].delflag=0;
|
||||
auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
|
||||
if (auth_fifo_pos >= AUTH_FIFO_SIZE)
|
||||
auth_fifo_pos = 0;
|
||||
auth_fifo[auth_fifo_pos].account_id = account.account_id;
|
||||
auth_fifo[auth_fifo_pos].login_id1 = account.login_id1;
|
||||
auth_fifo[auth_fifo_pos].login_id2 = account.login_id2;
|
||||
auth_fifo[auth_fifo_pos].sex = account.sex;
|
||||
auth_fifo[auth_fifo_pos].delflag = 0;
|
||||
auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
|
||||
auth_fifo_pos++;
|
||||
} else {
|
||||
} else { // if no char-server, don't send void list of servers, just disconnect the player with proper message
|
||||
WFIFOW(fd,0) = 0x81;
|
||||
WFIFOB(fd,2) = 1; // 01 = Server closed
|
||||
WFIFOSET(fd,3);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WFIFOHEAD(fd,23);
|
||||
} else { // auth failed
|
||||
WFIFOHEAD(fd, 23);
|
||||
if (login_config.log_login)
|
||||
{
|
||||
const char* error;
|
||||
@ -1536,7 +1531,7 @@ int parse_login(int fd)
|
||||
default : error = "Unknown Error."; break;
|
||||
}
|
||||
|
||||
sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %s')", loginlog_db, (unsigned int)ntohl(ipl), t_uid, result, error);
|
||||
sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %s')", loginlog_db, ipl, t_uid, result, error);
|
||||
|
||||
//query
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
@ -1547,7 +1542,7 @@ int parse_login(int fd)
|
||||
|
||||
if ((result == 1) && login_config.dynamic_pass_failure_ban && login_config.log_login) { // failed password
|
||||
sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%u' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
|
||||
loginlog_db,(unsigned int)ntohl(ipl), login_config.dynamic_pass_failure_ban_interval); //how many times filed account? in one ip.
|
||||
loginlog_db, ipl, login_config.dynamic_pass_failure_ban_interval); //how many times filed account? in one ip.
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
@ -1557,7 +1552,8 @@ int parse_login(int fd)
|
||||
sql_row = sql_res?mysql_fetch_row(sql_res):NULL; //row fetching
|
||||
|
||||
if (sql_row && (unsigned int)atoi(sql_row[0]) >= login_config.dynamic_pass_failure_ban_limit ) {
|
||||
sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], login_config.dynamic_pass_failure_ban_duration, t_uid);
|
||||
uint8* p = (uint8*)&ipl;
|
||||
sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL %d MINUTE ,'Password error ban: %s')", (uint8)p[3], (uint8)p[2], (uint8)p[1], login_config.dynamic_pass_failure_ban_duration, t_uid);
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
@ -1566,7 +1562,8 @@ int parse_login(int fd)
|
||||
if(sql_res) mysql_free_result(sql_res);
|
||||
}
|
||||
else if (result == -2){ //dynamic banned - add ip to ban list.
|
||||
sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", p[0], p[1], p[2], t_uid);
|
||||
uint8* p = (uint8*)&ipl;
|
||||
sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() + INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", (uint8)p[3], (uint8)p[2], (uint8)p[1], t_uid);
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
@ -1583,21 +1580,24 @@ int parse_login(int fd)
|
||||
}
|
||||
sql_res = mysql_store_result(&mysql_handle) ;
|
||||
sql_row = sql_res?mysql_fetch_row(sql_res):NULL;
|
||||
|
||||
//cannot connect login failed
|
||||
memset(WFIFOP(fd,0),'\0',23);
|
||||
WFIFOW(fd,0)=0x6a;
|
||||
WFIFOB(fd,2)=result;
|
||||
memset(WFIFOP(fd,0), '\0', 23);
|
||||
WFIFOW(fd,0) = 0x6a;
|
||||
WFIFOB(fd,2) = result;
|
||||
if (result == 6) { // 6 = Your are Prohibited to log in until %s
|
||||
char tmpstr[20];
|
||||
time_t ban_until_time = (sql_row) ? atol(sql_row[0]) : 0;
|
||||
strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time));
|
||||
tmpstr[19] = '\0';
|
||||
strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time)); tmpstr[19] = '\0';
|
||||
strncpy(WFIFOP(fd,3), tmpstr, 20); // ban timestamp goes here
|
||||
}
|
||||
WFIFOSET(fd,23);
|
||||
|
||||
if (sql_res) mysql_free_result(sql_res);
|
||||
}
|
||||
RFIFOSKIP(fd,packet_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x01db: // request password key
|
||||
if (session[fd]->session_data) {
|
||||
@ -1606,41 +1606,39 @@ int parse_login(int fd)
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
WFIFOHEAD(fd,4+md5keylen);
|
||||
WFIFOW(fd,0)=0x01dc;
|
||||
WFIFOW(fd,2)=4+md5keylen;
|
||||
memcpy(WFIFOP(fd,4),md5key,md5keylen);
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
RFIFOSKIP(fd,2);
|
||||
WFIFOHEAD(fd, 4 + md5keylen);
|
||||
WFIFOW(fd,0) = 0x01dc;
|
||||
WFIFOW(fd,2) = 4 + md5keylen;
|
||||
memcpy(WFIFOP(fd,4), md5key, md5keylen);
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2710: // request Char-server connection
|
||||
if(RFIFOREST(fd)<86)
|
||||
case 0x2710: // Connection request of a char-server
|
||||
if (RFIFOREST(fd) < 86)
|
||||
return 0;
|
||||
{
|
||||
char* server_name;
|
||||
uint32 server_ip;
|
||||
uint16 server_port;
|
||||
|
||||
WFIFOHEAD(fd, 3);
|
||||
memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH);
|
||||
account.userid[23] = '\0';
|
||||
memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH);
|
||||
account.passwd[23] = '\0';
|
||||
memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH); account.userid[23] = '\0';
|
||||
memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH); account.passwd[23] = '\0';
|
||||
account.passwdenc = 0;
|
||||
server_name = (char*)RFIFOP(fd,60);
|
||||
server_name[20] = '\0';
|
||||
ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
|
||||
server_name, RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
|
||||
p[0], p[1], p[2], p[3]);
|
||||
jstrescapecpy(t_uid,server_name);
|
||||
server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0';
|
||||
server_ip = ntohl(RFIFOL(fd, 54));
|
||||
server_port = ntohs(RFIFOW(fd, 58));
|
||||
ShowInfo("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)\n",
|
||||
server_name, CONVIP(server_ip), server_port, ip);
|
||||
jstrescapecpy(t_uid, server_name);
|
||||
if (login_config.log_login)
|
||||
{
|
||||
char t_login[50];
|
||||
jstrescapecpy(t_login,account.userid);
|
||||
sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')",
|
||||
loginlog_db, (unsigned int)ntohl(ipl),
|
||||
t_login, t_uid, t_uid,
|
||||
RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57),
|
||||
RFIFOW(fd, 58));
|
||||
loginlog_db, ipl, t_login, t_uid, t_uid, CONVIP(server_ip), server_port);
|
||||
|
||||
//query
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
@ -1648,19 +1646,18 @@ int parse_login(int fd)
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
}
|
||||
}
|
||||
result = mmo_auth(&account, fd);
|
||||
//printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
|
||||
|
||||
if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
|
||||
result = mmo_auth(&account, fd);
|
||||
if (result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1) {
|
||||
ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
|
||||
memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
|
||||
server[account.account_id].ip=RFIFOL(fd,54);
|
||||
server[account.account_id].port=RFIFOW(fd,58);
|
||||
memcpy(server[account.account_id].name,server_name,20);
|
||||
server[account.account_id].users=0;
|
||||
server[account.account_id].maintenance=RFIFOW(fd,82);
|
||||
server[account.account_id].new_=RFIFOW(fd,84);
|
||||
server_fd[account.account_id]=fd;
|
||||
server[account.account_id].ip = ntohl(RFIFOL(fd,54));
|
||||
server[account.account_id].port = ntohs(RFIFOW(fd,58));
|
||||
memcpy(server[account.account_id].name, server_name, 20);
|
||||
server[account.account_id].users = 0;
|
||||
server[account.account_id].maintenance = RFIFOW(fd,82);
|
||||
server[account.account_id].new_ = RFIFOW(fd,84);
|
||||
server_fd[account.account_id] = fd;
|
||||
sprintf(tmpsql,"DELETE FROM `sstatus` WHERE `index`='%d'", account.account_id);
|
||||
//query
|
||||
if(mysql_query(&mysql_handle, tmpsql)) {
|
||||
@ -1675,42 +1672,43 @@ int parse_login(int fd)
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
|
||||
}
|
||||
WFIFOW(fd,0)=0x2711;
|
||||
WFIFOB(fd,2)=0;
|
||||
WFIFOW(fd,0) = 0x2711;
|
||||
WFIFOB(fd,2) = 0;
|
||||
WFIFOSET(fd,3);
|
||||
session[fd]->func_parse=parse_fromchar;
|
||||
realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
|
||||
session[fd]->func_parse = parse_fromchar;
|
||||
realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
|
||||
// send GM account to char-server
|
||||
send_GM_accounts(fd);
|
||||
} else {
|
||||
WFIFOW(fd, 0) =0x2711;
|
||||
WFIFOB(fd, 2)=3;
|
||||
WFIFOSET(fd, 3);
|
||||
WFIFOW(fd,0) = 0x2711;
|
||||
WFIFOB(fd,2) = 3;
|
||||
WFIFOSET(fd,3);
|
||||
}
|
||||
}
|
||||
RFIFOSKIP(fd, 86);
|
||||
RFIFOSKIP(fd,86);
|
||||
return 0;
|
||||
|
||||
case 0x7530: // request Athena information
|
||||
{
|
||||
ShowInfo ("Athena version check...\n");
|
||||
WFIFOHEAD(fd,10);
|
||||
WFIFOW(fd,0)=0x7531;
|
||||
WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
|
||||
WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
|
||||
WFIFOB(fd,4)=ATHENA_REVISION;
|
||||
WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
|
||||
WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
|
||||
WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
|
||||
WFIFOW(fd,8)=ATHENA_MOD_VERSION;
|
||||
WFIFOW(fd,0) = 0x7531;
|
||||
WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
|
||||
WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
|
||||
WFIFOB(fd,4) = ATHENA_REVISION;
|
||||
WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
|
||||
WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
|
||||
WFIFOB(fd,7) = ATHENA_SERVER_LOGIN;
|
||||
WFIFOW(fd,8) = ATHENA_MOD_VERSION;
|
||||
WFIFOSET(fd,10);
|
||||
RFIFOSKIP(fd,2);
|
||||
ShowInfo ("Athena version check...\n");
|
||||
break;
|
||||
}
|
||||
case 0x7532:
|
||||
case 0x7532: // Request to end connection
|
||||
ShowStatus ("End of connection (ip: %s)" RETCODE, ip);
|
||||
session[fd]->eof = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ShowStatus ("Abnormal end of connection (ip: %s): Unknown packet 0x%x " RETCODE, ip, RFIFOW(fd,0));
|
||||
session[fd]->eof = 1;
|
||||
@ -1782,7 +1780,6 @@ int config_switch(const char *str)
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------
|
||||
// Reading Lan Support configuration
|
||||
//----------------------------------
|
||||
@ -1819,9 +1816,9 @@ int login_lan_config_read(const char *lancfgName)
|
||||
|
||||
if(strcmpi(w1, "subnet") == 0) {
|
||||
|
||||
subnet[subnet_count].mask = inet_addr(w2);
|
||||
subnet[subnet_count].char_ip = inet_addr(w3);
|
||||
subnet[subnet_count].map_ip = inet_addr(w4);
|
||||
subnet[subnet_count].mask = ntohl(inet_addr(w2));
|
||||
subnet[subnet_count].char_ip = ntohl(inet_addr(w3));
|
||||
subnet[subnet_count].map_ip = ntohl(inet_addr(w4));
|
||||
subnet[subnet_count].subnet = subnet[subnet_count].char_ip&subnet[subnet_count].mask;
|
||||
if (subnet[subnet_count].subnet != (subnet[subnet_count].map_ip&subnet[subnet_count].mask)) {
|
||||
ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
|
||||
@ -1851,9 +1848,9 @@ int ip_ban_flush(int tid, unsigned int tick, int id, int data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
//-----------------------------------
|
||||
// Reading main configuration file
|
||||
//-----------------------------------------------------
|
||||
//-----------------------------------
|
||||
int login_config_read(const char* cfgName)
|
||||
{
|
||||
char line[1024], w1[1024], w2[1024];
|
||||
@ -1867,11 +1864,12 @@ int login_config_read(const char* cfgName)
|
||||
{
|
||||
if (line[0] == '/' && line[1] == '/')
|
||||
continue;
|
||||
|
||||
if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) < 2)
|
||||
continue;
|
||||
|
||||
remove_control_chars((unsigned char *) w1);
|
||||
remove_control_chars((unsigned char *) w2);
|
||||
remove_control_chars((unsigned char *)w1);
|
||||
remove_control_chars((unsigned char *)w2);
|
||||
|
||||
if(!strcmpi(w1,"timestamp_format")) {
|
||||
strncpy(timestamp_format, w2, 20);
|
||||
@ -1890,6 +1888,9 @@ int login_config_read(const char* cfgName)
|
||||
login_config.login_port = (unsigned short)atoi(w2);
|
||||
ShowStatus("set login_port : %s\n",w2);
|
||||
}
|
||||
else if (!strcmpi(w1, "log_login"))
|
||||
login_config.log_login = config_switch(w2);
|
||||
|
||||
else if (!strcmpi(w1,"ipban"))
|
||||
login_config.ipban = config_switch(w2);
|
||||
else if (!strcmpi(w1,"dynamic_pass_failure_ban"))
|
||||
@ -1923,8 +1924,6 @@ int login_config_read(const char* cfgName)
|
||||
time_allowed = atoi(w2);
|
||||
else if (!strcmpi(w1, "online_check"))
|
||||
login_config.online_check = config_switch(w2);
|
||||
else if (!strcmpi(w1, "log_login"))
|
||||
login_config.log_login = config_switch(w2);
|
||||
else if (!strcmpi(w1,"use_dnsbl"))
|
||||
login_config.use_dnsbl = config_switch(w2);
|
||||
else if (!strcmpi(w1,"dnsbl_servers"))
|
||||
|
@ -42,8 +42,8 @@ struct mmo_account {
|
||||
|
||||
struct mmo_char_server {
|
||||
char name[20];
|
||||
long ip;
|
||||
short port;
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
int users;
|
||||
int maintenance;
|
||||
int new_;
|
||||
|
147
src/map/chrif.c
147
src/map/chrif.c
@ -24,18 +24,14 @@
|
||||
#include "status.h"
|
||||
#include "mercenary.h"
|
||||
|
||||
//Updated table (only doc^^) [Sirius]
|
||||
//Used Packets: U->2af8
|
||||
//Free Packets: F->2af8
|
||||
|
||||
struct dbt *auth_db;
|
||||
|
||||
static const int packet_len_table[0x3d] = {
|
||||
static const int packet_len_table[0x3d] = { // U - used, F - free
|
||||
60, 3,-1,27,10,-1, 6,-1, // 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
|
||||
6,-1,18, 7,-1,49,30,10, // 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
|
||||
6,30,-1,10,86, 7,44,34, // 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
|
||||
0,-1,10, 6,11,-1, 0, 0, // 2b10-2b17: U->2b10, U->2b11, U->2b12, U->2b13, U->2b14, U->2b15, U->2b16, U->2b17
|
||||
-1,-1,-1,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
|
||||
-1,-1,-1,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
|
||||
-1,10, 8,-1,-1,-1,-1,-1, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, F->2b24, F->2b25, F->2b26, F->2b27
|
||||
};
|
||||
|
||||
@ -89,8 +85,8 @@ int chrif_connected = 0;
|
||||
int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex]
|
||||
int srvinfo;
|
||||
static char char_ip_str[128];
|
||||
static in_addr_t char_ip= 0;
|
||||
static int char_port = 6121;
|
||||
static uint32 char_ip = 0;
|
||||
static uint16 char_port = 6121;
|
||||
static char userid[NAME_LENGTH], passwd[NAME_LENGTH];
|
||||
static int chrif_state = 0;
|
||||
static int char_init_done = 0;
|
||||
@ -103,29 +99,20 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
|
||||
//This define should spare writing the check in every function. [Skotlex]
|
||||
#define chrif_check(a) { if(!chrif_isconnect()) return a; }
|
||||
|
||||
// 設定ファイル読み込み関係
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
|
||||
// sets char-server's user id
|
||||
void chrif_setuserid(char *id)
|
||||
{
|
||||
memcpy(userid, id, NAME_LENGTH);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
// sets char-server's password
|
||||
void chrif_setpasswd(char *pwd)
|
||||
{
|
||||
memcpy(passwd, pwd, NAME_LENGTH);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
// security check, prints warning if using default password
|
||||
void chrif_checkdefaultlogin(void)
|
||||
{
|
||||
if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
|
||||
@ -139,11 +126,8 @@ void chrif_checkdefaultlogin(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
int chrif_setip(const char *ip)
|
||||
// sets char-server's ip address
|
||||
int chrif_setip(const char* ip)
|
||||
{
|
||||
char ip_str[16];
|
||||
char_ip = host2ip(ip);
|
||||
@ -156,30 +140,23 @@ int chrif_setip(const char *ip)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
void chrif_setport(int port)
|
||||
// sets char-server's port number
|
||||
void chrif_setport(uint16 port)
|
||||
{
|
||||
char_port = port;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
// says whether the char-server is connected or not
|
||||
int chrif_isconnect(void)
|
||||
{
|
||||
return (char_fd > 0 && session[char_fd] != NULL && chrif_state == 2);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Saves char.
|
||||
* Flag = 1: Character is quitting.
|
||||
* Saves character data.
|
||||
* Flag = 1: Character is quitting
|
||||
* Flag = 2: Character is changing map-servers
|
||||
*------------------------------------------
|
||||
*/
|
||||
*------------------------------------------*/
|
||||
int chrif_save(struct map_session_data *sd, int flag)
|
||||
{
|
||||
nullpo_retr(-1, sd);
|
||||
@ -226,10 +203,7 @@ int chrif_save(struct map_session_data *sd, int flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
// connects to char-server (plaintext)
|
||||
int chrif_connect(int fd)
|
||||
{
|
||||
ShowStatus("Logging in to char server...\n", char_fd);
|
||||
@ -238,17 +212,14 @@ int chrif_connect(int fd)
|
||||
memcpy(WFIFOP(fd,2), userid, NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,26), passwd, NAME_LENGTH);
|
||||
WFIFOL(fd,50) = 0;
|
||||
WFIFOL(fd,54) = clif_getip_long();
|
||||
WFIFOW(fd,58) = clif_getport(); // [Valaris] thanks to fov
|
||||
WFIFOL(fd,54) = htonl(clif_getip());
|
||||
WFIFOW(fd,58) = htons(clif_getport());
|
||||
WFIFOSET(fd,60);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* マップ送信
|
||||
*------------------------------------------
|
||||
*/
|
||||
// sends maps to char-server
|
||||
int chrif_sendmap(int fd)
|
||||
{
|
||||
int i;
|
||||
@ -263,36 +234,31 @@ int chrif_sendmap(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* マップ受信
|
||||
*------------------------------------------
|
||||
*/
|
||||
// receive maps from some other map-server (relayed via char-server)
|
||||
int chrif_recvmap(int fd)
|
||||
{
|
||||
int i, j, ip, port;
|
||||
unsigned char *p = (unsigned char *)&ip;
|
||||
int i, j;
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
RFIFOHEAD(fd);
|
||||
ip = RFIFOL(fd,4);
|
||||
port = RFIFOW(fd,8);
|
||||
ip = ntohl(RFIFOL(fd,4));
|
||||
port = ntohs(RFIFOW(fd,8));
|
||||
for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) {
|
||||
map_setipport(RFIFOW(fd,i), ip, port);
|
||||
// if (battle_config.etc_log)
|
||||
// printf("recv map %d %s\n", j, RFIFOP(fd,i));
|
||||
}
|
||||
if (battle_config.etc_log)
|
||||
ShowStatus("recv map on %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j);
|
||||
ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
|
||||
|
||||
other_mapserver_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Delete maps of other servers, (if an other mapserver is going OFF)
|
||||
*------------------------------------------
|
||||
*/
|
||||
int chrif_removemap(int fd){
|
||||
int i, j, ip, port;
|
||||
unsigned char *p = (unsigned char *)&ip;
|
||||
// remove specified maps (used when some other map-server disconnects)
|
||||
int chrif_removemap(int fd)
|
||||
{
|
||||
int i, j;
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
RFIFOHEAD(fd);
|
||||
|
||||
ip = RFIFOL(fd, 4);
|
||||
@ -304,11 +270,13 @@ int chrif_removemap(int fd){
|
||||
|
||||
other_mapserver_count--;
|
||||
if(battle_config.etc_log)
|
||||
ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j);
|
||||
ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int chrif_save_ack(int fd) {
|
||||
// received after a character has been "final saved" on the char-server
|
||||
int chrif_save_ack(int fd)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
RFIFOHEAD(fd);
|
||||
sd = map_id2sd(RFIFOL(fd,2));
|
||||
@ -318,13 +286,10 @@ int chrif_save_ack(int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* マップ鯖間移動のためのデータ準備要求
|
||||
*------------------------------------------
|
||||
*/
|
||||
int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, int ip, short port)
|
||||
// request to move a character between mapservers
|
||||
int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, uint32 ip, uint16 port)
|
||||
{
|
||||
int s_ip;
|
||||
uint32 s_ip;
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
@ -337,7 +302,7 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
|
||||
}
|
||||
|
||||
if (sd->fd && sd->fd < fd_max && session[sd->fd])
|
||||
s_ip = session[sd->fd]->client_addr.sin_addr.s_addr;
|
||||
s_ip = session[sd->fd]->client_addr;
|
||||
else //Not connected? Can't retrieve IP
|
||||
s_ip = 0;
|
||||
|
||||
@ -350,19 +315,16 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
|
||||
WFIFOW(char_fd,18) = map;
|
||||
WFIFOW(char_fd,20) = x;
|
||||
WFIFOW(char_fd,22) = y;
|
||||
WFIFOL(char_fd,24) = ip;
|
||||
WFIFOW(char_fd,28) = port;
|
||||
WFIFOL(char_fd,24) = htonl(ip);
|
||||
WFIFOW(char_fd,28) = htons(port);
|
||||
WFIFOB(char_fd,30) = sd->status.sex;
|
||||
WFIFOL(char_fd,31) = s_ip;
|
||||
WFIFOL(char_fd,31) = htonl(s_ip); // not used
|
||||
WFIFOSET(char_fd,35);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* マップ鯖間移動ack
|
||||
*------------------------------------------
|
||||
*/
|
||||
// map-server change request acknowledgement (positive or negative)
|
||||
int chrif_changemapserverack(int fd)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
@ -380,7 +342,7 @@ int chrif_changemapserverack(int fd)
|
||||
return 0;
|
||||
}
|
||||
sprintf(mapname, "%s.gat", mapindex_id2name(RFIFOW(fd,18)));
|
||||
clif_changemapserver(sd, mapname, RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28));
|
||||
clif_changemapserver(sd, mapname, RFIFOW(fd,20), RFIFOW(fd,22), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28)));
|
||||
|
||||
//Player has been saved already, remove him from memory. [Skotlex]
|
||||
map_quit(sd);
|
||||
@ -390,8 +352,7 @@ int chrif_changemapserverack(int fd)
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
*------------------------------------------*/
|
||||
int chrif_connectack(int fd)
|
||||
{
|
||||
RFIFOHEAD(fd);
|
||||
@ -568,7 +529,7 @@ int auth_db_cleanup(int tid, unsigned int tick, int id, int data) {
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
|
||||
int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip)
|
||||
{
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
@ -581,7 +542,7 @@ int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
|
||||
WFIFOL(char_fd, 2) = sd->bl.id;
|
||||
WFIFOL(char_fd, 6) = sd->login_id1;
|
||||
WFIFOL(char_fd,10) = sd->login_id2;
|
||||
WFIFOL(char_fd,14) = s_ip;
|
||||
WFIFOL(char_fd,14) = htonl(s_ip);
|
||||
WFIFOSET(char_fd,18);
|
||||
|
||||
return 0;
|
||||
@ -693,7 +654,6 @@ int chrif_changesex(int id, int sex) {
|
||||
WFIFOW(char_fd,2) = 9;
|
||||
WFIFOL(char_fd,4) = id;
|
||||
WFIFOB(char_fd,8) = sex;
|
||||
// ShowInfo("chrif : sent 0x3000(changesex)\n");
|
||||
WFIFOSET(char_fd,9);
|
||||
return 0;
|
||||
}
|
||||
@ -1040,7 +1000,8 @@ int chrif_accountban(int fd)
|
||||
|
||||
//Disconnect the player out of the game, simple packet
|
||||
//packet.w AID.L WHY.B 2+4+1 = 7byte
|
||||
int chrif_disconnectplayer(int fd){
|
||||
int chrif_disconnectplayer(int fd)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
RFIFOHEAD(fd);
|
||||
|
||||
@ -1419,7 +1380,7 @@ int chrif_disconnect(int fd) {
|
||||
|
||||
void chrif_update_ip(int fd)
|
||||
{
|
||||
unsigned long new_ip;
|
||||
uint32 new_ip;
|
||||
WFIFOHEAD(fd, 6);
|
||||
new_ip = host2ip(char_ip_str);
|
||||
if (new_ip && new_ip != char_ip)
|
||||
@ -1428,7 +1389,7 @@ void chrif_update_ip(int fd)
|
||||
new_ip = clif_refresh_ip();
|
||||
if (!new_ip) return; //No change
|
||||
WFIFOW(fd, 0) = 0x2736;
|
||||
WFIFOL(fd, 2) = new_ip;
|
||||
WFIFOL(fd, 2) = htonl(new_ip);
|
||||
WFIFOSET(fd, 6);
|
||||
}
|
||||
|
||||
@ -1452,7 +1413,7 @@ int chrif_parse(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (RFIFOREST(fd) >= 2 && !session[fd]->eof) { //Infinite loop on broken pipe fix. [Skotlex]
|
||||
while (RFIFOREST(fd) >= 2) { //Infinite loop on broken pipe fix. [Skotlex]
|
||||
RFIFOHEAD(fd);
|
||||
cmd = RFIFOW(fd,0);
|
||||
if (cmd < 0x2af8 || cmd >= 0x2af8 + (sizeof(packet_len_table) / sizeof(packet_len_table[0])) ||
|
||||
|
@ -12,11 +12,11 @@ struct auth_node{
|
||||
unsigned int node_created; //For node auto-deleting
|
||||
};
|
||||
|
||||
void chrif_setuserid(char*);
|
||||
void chrif_setpasswd(char*);
|
||||
void chrif_setuserid(char* id);
|
||||
void chrif_setpasswd(char* pwd);
|
||||
void chrif_checkdefaultlogin(void);
|
||||
int chrif_setip(const char*);
|
||||
void chrif_setport(int);
|
||||
int chrif_setip(const char* ip);
|
||||
void chrif_setport(uint16 port);
|
||||
|
||||
int chrif_isconnect(void);
|
||||
|
||||
@ -27,9 +27,9 @@ void chrif_authreq(struct map_session_data *);
|
||||
void chrif_authok(int fd);
|
||||
int chrif_scdata_request(int account_id, int char_id);
|
||||
int chrif_save(struct map_session_data*, int flag);
|
||||
int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip);
|
||||
int chrif_charselectreq(struct map_session_data*sd, uint32 s_ip);
|
||||
void check_fake_id(int fd, struct map_session_data *sd, int target_id);
|
||||
int chrif_changemapserver(struct map_session_data *sd,short map,int x,int y,int ip,short port);
|
||||
int chrif_changemapserver(struct map_session_data*sd, short map, int x, int y, uint32 ip, uint16 port);
|
||||
|
||||
int chrif_searchcharid(int char_id);
|
||||
int chrif_changegm(int id,const char *pass,int len);
|
||||
|
@ -96,9 +96,9 @@ struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
|
||||
//Guarantees that the given string does not exceeds the allowed size, as well as making sure it's null terminated. [Skotlex\]
|
||||
#define mes_len_check(mes, len, max) if (len > max) { mes[max-1] = '\0'; len = max; } else mes[len-1] = '\0';
|
||||
static char map_ip_str[128];
|
||||
static in_addr_t map_ip;
|
||||
static in_addr_t bind_ip = INADDR_ANY;
|
||||
static int map_port = 5121;
|
||||
static uint32 map_ip;
|
||||
static uint32 bind_ip = INADDR_ANY;
|
||||
static uint16 map_port = 5121;
|
||||
int map_fd;
|
||||
|
||||
//These two will be used to verify the incoming player's validity.
|
||||
@ -142,7 +142,7 @@ void clif_setbindip(const char* ip)
|
||||
* map鯖のport設定
|
||||
*------------------------------------------
|
||||
*/
|
||||
void clif_setport(int port)
|
||||
void clif_setport(uint16 port)
|
||||
{
|
||||
map_port = port;
|
||||
}
|
||||
@ -151,27 +151,21 @@ void clif_setport(int port)
|
||||
* map鯖のip読み出し
|
||||
*------------------------------------------
|
||||
*/
|
||||
in_addr_t clif_getip(void)
|
||||
uint32 clif_getip(void)
|
||||
{
|
||||
return map_ip;
|
||||
}
|
||||
|
||||
//Returns the ip casted as a basic type, to avoid needing to include the socket/net related libs by calling modules.
|
||||
unsigned long clif_getip_long(void)
|
||||
{
|
||||
return (unsigned long)map_ip;
|
||||
}
|
||||
|
||||
//Refreshes map_server ip, returns the new ip if the ip changed, otherwise it returns 0.
|
||||
unsigned long clif_refresh_ip(void)
|
||||
uint32 clif_refresh_ip(void)
|
||||
{
|
||||
in_addr_t new_ip;
|
||||
uint32 new_ip;
|
||||
|
||||
new_ip = host2ip(map_ip_str);
|
||||
if (new_ip && new_ip != map_ip) {
|
||||
map_ip = new_ip;
|
||||
ShowInfo("Updating IP resolution of [%s].\n",map_ip_str);
|
||||
return (unsigned long)map_ip;
|
||||
ShowInfo("Updating IP resolution of [%s].\n", map_ip_str);
|
||||
return map_ip;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -180,7 +174,7 @@ unsigned long clif_refresh_ip(void)
|
||||
* map鯖のport読み出し
|
||||
*------------------------------------------
|
||||
*/
|
||||
int clif_getport(void)
|
||||
uint16 clif_getport(void)
|
||||
{
|
||||
return map_port;
|
||||
}
|
||||
@ -1625,10 +1619,10 @@ int clif_changemap(struct map_session_data *sd, short map, int x, int y) {
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, int ip, int port) {
|
||||
* Tells the client to connect to another map-server
|
||||
*------------------------------------------*/
|
||||
int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, uint32 ip, uint16 port)
|
||||
{
|
||||
int fd;
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
@ -1641,8 +1635,8 @@ int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x
|
||||
WFIFOB(fd,17) = 0; //Null terminator for mapname
|
||||
WFIFOW(fd,18) = x;
|
||||
WFIFOW(fd,20) = y;
|
||||
WFIFOL(fd,22) = ip;
|
||||
WFIFOW(fd,26) = port;
|
||||
WFIFOL(fd,22) = htonl(ip);
|
||||
WFIFOW(fd,26) = port; // /!\ must be sent in intel host byte order /!\ (client bug)
|
||||
WFIFOSET(fd, packet_len(0x92));
|
||||
|
||||
return 0;
|
||||
@ -8862,7 +8856,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
|
||||
/* Rovert's Prevent logout option - Fixed [Valaris] */
|
||||
if (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
|
||||
{ //Send to char-server for character selection.
|
||||
chrif_charselectreq(sd, session[fd]->client_addr.sin_addr.s_addr);
|
||||
chrif_charselectreq(sd, session[fd]->client_addr);
|
||||
} else {
|
||||
WFIFOHEAD(fd,packet_len(0x18b));
|
||||
WFIFOW(fd,0)=0x18b;
|
||||
@ -11746,7 +11740,8 @@ void clif_parse_debug(int fd,struct map_session_data *sd)
|
||||
* socket.cのdo_parsepacketから呼び出される
|
||||
*------------------------------------------
|
||||
*/
|
||||
int clif_parse(int fd) {
|
||||
int clif_parse(int fd)
|
||||
{
|
||||
int packet_len = 0, cmd, packet_ver, err, dump = 0;
|
||||
TBL_PC *sd;
|
||||
RFIFOHEAD(fd);
|
||||
@ -11772,8 +11767,8 @@ int clif_parse(int fd) {
|
||||
map_quit(sd);
|
||||
}
|
||||
} else {
|
||||
unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr;
|
||||
ShowInfo("Closed connection from '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", ip[0],ip[1],ip[2],ip[3]);
|
||||
uint32 ip = session[fd]->client_addr;
|
||||
ShowInfo("Closed connection from '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", CONVIP(ip));
|
||||
}
|
||||
do_close(fd);
|
||||
return 0;
|
||||
@ -12321,8 +12316,8 @@ static int packetdb_readdb(void)
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
int do_init_clif(void) {
|
||||
|
||||
int do_init_clif(void)
|
||||
{
|
||||
clif_config.packet_db_ver = -1; // the main packet version of the DB
|
||||
memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]
|
||||
|
||||
|
@ -52,11 +52,11 @@ extern struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
|
||||
|
||||
int clif_setip(const char* ip);
|
||||
void clif_setbindip(const char* ip);
|
||||
void clif_setport(int);
|
||||
void clif_setport(uint16 port);
|
||||
|
||||
unsigned long clif_getip_long(void);
|
||||
unsigned long clif_refresh_ip(void);
|
||||
int clif_getport(void);
|
||||
uint32 clif_getip(void);
|
||||
uint32 clif_refresh_ip(void);
|
||||
uint16 clif_getport(void);
|
||||
int clif_countusers(void);
|
||||
void clif_setwaitclose(int);
|
||||
|
||||
@ -75,7 +75,7 @@ int clif_spawn(struct block_list*); //area
|
||||
int clif_walkok(struct map_session_data*); // self
|
||||
void clif_move(struct unit_data *ud); //area
|
||||
int clif_changemap(struct map_session_data*,short,int,int); //self
|
||||
int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, int ip, int port); //self
|
||||
int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, uint32 ip, uint16 port); //self
|
||||
int clif_blown(struct block_list *); // area
|
||||
int clif_slide(struct block_list *,int,int); // area
|
||||
int clif_fixpos(struct block_list *); // area
|
||||
|
@ -2077,9 +2077,9 @@ int map_mapindex2mapid(unsigned short mapindex) {
|
||||
|
||||
/*==========================================
|
||||
* 他鯖map名からip,port?換
|
||||
*------------------------------------------
|
||||
*/
|
||||
int map_mapname2ipport(unsigned short name,int *ip,int *port) {
|
||||
*------------------------------------------*/
|
||||
int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port)
|
||||
{
|
||||
struct map_data_other_server *mdos=NULL;
|
||||
|
||||
mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)name);
|
||||
@ -2349,16 +2349,17 @@ static void* create_map_data_other_server(DBKey key, va_list args) {
|
||||
}
|
||||
/*==========================================
|
||||
* 他鯖管理のマップをdbに追加
|
||||
*------------------------------------------
|
||||
*/
|
||||
int map_setipport(unsigned short mapindex,unsigned long ip,int port) {
|
||||
*------------------------------------------*/
|
||||
|
||||
int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
|
||||
{
|
||||
struct map_data_other_server *mdos=NULL;
|
||||
|
||||
mdos=(struct map_data_other_server *)uidb_ensure(map_db,(unsigned int)mapindex, create_map_data_other_server);
|
||||
|
||||
if(mdos->gat) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
|
||||
return 0;
|
||||
if(ip == clif_getip_long() && port == clif_getport()) {
|
||||
if(ip == clif_getip() && port == clif_getport()) {
|
||||
//That's odd, we received info that we are the ones with this map, but... we don't have it.
|
||||
ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex));
|
||||
exit(1);
|
||||
@ -2388,12 +2389,10 @@ int map_eraseallipport(void) {
|
||||
|
||||
/*==========================================
|
||||
* 他鯖管理のマップをdbから削除
|
||||
*------------------------------------------
|
||||
*/
|
||||
int map_eraseipport(unsigned short mapindex,unsigned long ip,int port)
|
||||
*------------------------------------------*/
|
||||
int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
|
||||
{
|
||||
struct map_data_other_server *mdos;
|
||||
// unsigned char *p=(unsigned char *)&ip;
|
||||
|
||||
mdos = uidb_get(map_db,(unsigned int)mapindex);
|
||||
if(!mdos || mdos->gat) //Map either does not exists or is a local map.
|
||||
|
@ -1109,8 +1109,8 @@ struct map_data_other_server {
|
||||
char name[MAP_NAME_LENGTH];
|
||||
unsigned short index; //Index is the map index used by the mapindex* functions.
|
||||
unsigned char *gat; // NULL固定にして判断
|
||||
unsigned long ip;
|
||||
unsigned int port;
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
};
|
||||
|
||||
struct flooritem_data {
|
||||
@ -1339,9 +1339,9 @@ struct map_session_data * map_id2sd(int);
|
||||
struct block_list * map_id2bl(int);
|
||||
int map_mapindex2mapid(unsigned short mapindex);
|
||||
int map_mapname2mapid(const char* name);
|
||||
int map_mapname2ipport(unsigned short,int*,int*);
|
||||
int map_setipport(unsigned short map,unsigned long ip,int port);
|
||||
int map_eraseipport(unsigned short map,unsigned long ip,int port);
|
||||
int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port);
|
||||
int map_setipport(unsigned short map, uint32 ip, uint16 port);
|
||||
int map_eraseipport(unsigned short map, uint32 ip, uint16 port);
|
||||
int map_eraseallipport(void);
|
||||
void map_addiddb(struct block_list *);
|
||||
void map_deliddb(struct block_list *bl);
|
||||
|
15
src/map/pc.c
15
src/map/pc.c
@ -698,20 +698,20 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
|
||||
sd->state.event_kill_mob = 1;
|
||||
|
||||
{ //Add IP field
|
||||
unsigned char *ip = (unsigned char *) &session[sd->fd]->client_addr.sin_addr;
|
||||
uint32 ip = session[sd->fd]->client_addr;
|
||||
if (pc_isGM(sd))
|
||||
ShowInfo("GM '"CL_WHITE"%s"CL_RESET"' logged in."
|
||||
" (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
|
||||
" Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"',"
|
||||
" GM Level '"CL_WHITE"%d"CL_RESET"').\n",
|
||||
sd->status.name, sd->status.account_id, sd->status.char_id,
|
||||
sd->packet_ver, ip[0],ip[1],ip[2],ip[3], pc_isGM(sd));
|
||||
sd->packet_ver, CONVIP(ip), pc_isGM(sd));
|
||||
else
|
||||
ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in."
|
||||
" (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
|
||||
" Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"').\n",
|
||||
sd->status.name, sd->status.account_id, sd->status.char_id,
|
||||
sd->packet_ver, ip[0],ip[1],ip[2],ip[3]);
|
||||
sd->packet_ver, CONVIP(ip));
|
||||
}
|
||||
|
||||
// Send friends list
|
||||
@ -3371,10 +3371,11 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
|
||||
sd->regen.state.gc = 0;
|
||||
}
|
||||
|
||||
if(m<0){
|
||||
if(sd->mapindex){
|
||||
int ip,port;
|
||||
if(map_mapname2ipport(mapindex,&ip,&port)==0){
|
||||
if(m<0) {
|
||||
if(sd->mapindex) {
|
||||
uint32 ip;
|
||||
uint16 port;
|
||||
if(map_mapname2ipport(mapindex,&ip,&port)==0) {
|
||||
unit_remove_map(&sd->bl,clrtype);
|
||||
sd->mapindex = mapindex;
|
||||
sd->bl.x=x;
|
||||
|
Loading…
x
Reference in New Issue
Block a user