|
|
1 | |
1 | /* |
2 | /* |
2 | * static char *rcsid_metaserver_c = |
3 | * static char *rcsid_metaserver_c = |
3 | * "$Id: metaserver.C,v 1.2 2006/08/29 08:01:38 root Exp $"; |
4 | * "$Id: metaserver.C,v 1.3 2006/09/10 13:43:33 root Exp $"; |
4 | */ |
5 | */ |
5 | |
6 | |
6 | /* |
7 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
8 | CrossFire, A Multiplayer game for X-windows |
8 | |
9 | |
… | |
… | |
32 | * Meta-server related functions. |
33 | * Meta-server related functions. |
33 | */ |
34 | */ |
34 | |
35 | |
35 | #include <global.h> |
36 | #include <global.h> |
36 | |
37 | |
37 | #ifndef WIN32 /* ---win32 exclude unix header files */ |
38 | #ifndef WIN32 /* ---win32 exclude unix header files */ |
38 | #include <sys/types.h> |
39 | # include <sys/types.h> |
39 | #include <sys/socket.h> |
40 | # include <sys/socket.h> |
40 | #include <netinet/in.h> |
41 | # include <netinet/in.h> |
41 | #include <netdb.h> |
42 | # include <netdb.h> |
42 | #include <arpa/inet.h> |
43 | # include <arpa/inet.h> |
43 | |
44 | |
44 | #endif /* end win32 */ |
45 | #endif /* end win32 */ |
45 | |
46 | |
46 | static int metafd=-1; |
47 | static int metafd = -1; |
47 | static struct sockaddr_in sock; |
48 | static struct sockaddr_in sock; |
48 | |
49 | |
49 | /** |
50 | /** |
50 | * Connects to metaserver. |
51 | * Connects to metaserver. |
51 | * |
52 | * |
52 | * Its only called once. If we are not |
53 | * Its only called once. If we are not |
53 | * trying to contact the metaserver of the connection attempt fails, metafd will be |
54 | * trying to contact the metaserver of the connection attempt fails, metafd will be |
54 | * set to -1. We use this instead of messing with the settings.meta_on so that |
55 | * set to -1. We use this instead of messing with the settings.meta_on so that |
55 | * that can be examined to at least see what the user was trying to do. |
56 | * that can be examined to at least see what the user was trying to do. |
56 | */ |
57 | */ |
|
|
58 | void |
57 | void metaserver_init(void) |
59 | metaserver_init (void) |
58 | { |
60 | { |
59 | |
61 | |
60 | #ifdef WIN32 /* ***win32 metaserver_init(): init win32 socket */ |
62 | #ifdef WIN32 /* ***win32 metaserver_init(): init win32 socket */ |
61 | struct hostent *hostbn; |
63 | struct hostent *hostbn; |
62 | int temp = 1; |
64 | int temp = 1; |
63 | #endif |
65 | #endif |
64 | |
66 | |
65 | if (!settings.meta_on) { |
67 | if (!settings.meta_on) |
|
|
68 | { |
66 | metafd=-1; |
69 | metafd = -1; |
67 | return; |
70 | return; |
68 | } |
71 | } |
69 | |
72 | |
70 | if (isdigit(settings.meta_server[0])) |
73 | if (isdigit (settings.meta_server[0])) |
71 | sock.sin_addr.s_addr = inet_addr(settings.meta_server); |
74 | sock.sin_addr.s_addr = inet_addr (settings.meta_server); |
72 | else { |
75 | else |
|
|
76 | { |
73 | struct hostent *hostbn = gethostbyname(settings.meta_server); |
77 | struct hostent *hostbn = gethostbyname (settings.meta_server); |
|
|
78 | |
74 | if (hostbn == NULL) { |
79 | if (hostbn == NULL) |
|
|
80 | { |
75 | LOG(llevDebug,"metaserver_init: Unable to resolve hostname %s\n", settings.meta_server); |
81 | LOG (llevDebug, "metaserver_init: Unable to resolve hostname %s\n", settings.meta_server); |
76 | return; |
82 | return; |
77 | } |
83 | } |
78 | memcpy(&sock.sin_addr, hostbn->h_addr, hostbn->h_length); |
84 | memcpy (&sock.sin_addr, hostbn->h_addr, hostbn->h_length); |
79 | } |
85 | } |
80 | #ifdef WIN32 /* ***win32 metaserver_init(): init win32 socket */ |
86 | #ifdef WIN32 /* ***win32 metaserver_init(): init win32 socket */ |
81 | ioctlsocket(metafd, FIONBIO , &temp); |
87 | ioctlsocket (metafd, FIONBIO, &temp); |
82 | #else |
88 | #else |
83 | fcntl(metafd, F_SETFL, O_NONBLOCK); |
89 | fcntl (metafd, F_SETFL, O_NONBLOCK); |
84 | #endif |
90 | #endif |
85 | if ((metafd=socket(AF_INET, SOCK_DGRAM, 0))==-1) { |
91 | if ((metafd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) |
|
|
92 | { |
86 | LOG(llevDebug,"metaserver_init: Unable to create socket, err %d\n", errno); |
93 | LOG (llevDebug, "metaserver_init: Unable to create socket, err %d\n", errno); |
87 | return; |
94 | return; |
88 | } |
95 | } |
89 | sock.sin_family = AF_INET; |
96 | sock.sin_family = AF_INET; |
90 | sock.sin_port = htons(settings.meta_port); |
97 | sock.sin_port = htons (settings.meta_port); |
91 | |
98 | |
92 | /* No hostname specified, so lets try to figure one out */ |
99 | /* No hostname specified, so lets try to figure one out */ |
93 | if (settings.meta_host[0]==0) { |
100 | if (settings.meta_host[0] == 0) |
|
|
101 | { |
94 | char hostname[MAX_BUF], domain[MAX_BUF]; |
102 | char hostname[MAX_BUF], domain[MAX_BUF]; |
|
|
103 | |
95 | if (gethostname(hostname, MAX_BUF-1)) { |
104 | if (gethostname (hostname, MAX_BUF - 1)) |
|
|
105 | { |
96 | LOG(llevDebug,"metaserver_init: gethostname failed - will not report hostname\n"); |
106 | LOG (llevDebug, "metaserver_init: gethostname failed - will not report hostname\n"); |
97 | return; |
107 | return; |
98 | } |
108 | } |
99 | |
109 | |
100 | #ifdef WIN32 /* ***win32 metaserver_init(): gethostbyname! */ |
110 | #ifdef WIN32 /* ***win32 metaserver_init(): gethostbyname! */ |
101 | hostbn = gethostbyname(hostname); |
111 | hostbn = gethostbyname (hostname); |
102 | if (hostbn != (struct hostent *) NULL) /* quick hack */ |
112 | if (hostbn != (struct hostent *) NULL) /* quick hack */ |
103 | memcpy(domain, hostbn->h_addr, hostbn->h_length); |
113 | memcpy (domain, hostbn->h_addr, hostbn->h_length); |
104 | |
114 | |
105 | if (hostbn == (struct hostent *) NULL) { |
115 | if (hostbn == (struct hostent *) NULL) |
|
|
116 | { |
106 | #else |
117 | #else |
107 | if (getdomainname(domain, MAX_BUF-1)) { |
118 | if (getdomainname (domain, MAX_BUF - 1)) |
|
|
119 | { |
108 | #endif /* win32 */ |
120 | #endif /* win32 */ |
109 | LOG(llevDebug,"metaserver_init: getdomainname failed - will not report hostname\n"); |
121 | LOG (llevDebug, "metaserver_init: getdomainname failed - will not report hostname\n"); |
110 | return; |
122 | return; |
111 | } |
123 | } |
112 | /* Potential overrun here but unlikely to occur */ |
124 | /* Potential overrun here but unlikely to occur */ |
113 | sprintf(settings.meta_host,"%s.%s", hostname, domain); |
125 | sprintf (settings.meta_host, "%s.%s", hostname, domain); |
114 | } |
126 | } |
115 | } |
127 | } |
116 | |
128 | |
117 | /** |
129 | /** |
118 | * Updates our info in the metaserver |
130 | * Updates our info in the metaserver |
119 | */ |
131 | */ |
|
|
132 | void |
120 | void metaserver_update(void) |
133 | metaserver_update (void) |
121 | { |
134 | { |
122 | char data[MAX_BUF], num_players=0; |
135 | char data[MAX_BUF], num_players = 0; |
123 | player *pl; |
136 | player *pl; |
124 | |
137 | |
125 | if (metafd == -1) return; /* No valid connection */ |
138 | if (metafd == -1) |
|
|
139 | return; /* No valid connection */ |
126 | |
140 | |
127 | /* We could use socket_info.nconns, but that is not quite as accurate, |
141 | /* We could use socket_info.nconns, but that is not quite as accurate, |
128 | * as connections in the progress of being established, are listening |
142 | * as connections in the progress of being established, are listening |
129 | * but don't have a player, etc. The checks below are basically the |
143 | * but don't have a player, etc. The checks below are basically the |
130 | * same as for the who commands with the addition that WIZ, AFK, and BOT |
144 | * same as for the who commands with the addition that WIZ, AFK, and BOT |
131 | * players are not counted. |
145 | * players are not counted. |
132 | */ |
146 | */ |
133 | for (pl=first_player; pl!=NULL; pl=pl->next) { |
147 | for (pl = first_player; pl != NULL; pl = pl->next) |
|
|
148 | { |
134 | if (pl->ob->map == NULL) continue; |
149 | if (pl->ob->map == NULL) |
|
|
150 | continue; |
135 | if (pl->hidden) continue; |
151 | if (pl->hidden) |
|
|
152 | continue; |
136 | if (QUERY_FLAG(pl->ob, FLAG_WIZ)) continue; |
153 | if (QUERY_FLAG (pl->ob, FLAG_WIZ)) |
|
|
154 | continue; |
137 | if (QUERY_FLAG(pl->ob, FLAG_AFK)) continue; |
155 | if (QUERY_FLAG (pl->ob, FLAG_AFK)) |
|
|
156 | continue; |
138 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) continue; |
157 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
|
|
158 | continue; |
139 | //if (pl->socket.is_bot) continue; |
159 | //if (pl->socket.is_bot) continue; |
140 | num_players++; |
160 | num_players++; |
141 | } |
161 | } |
142 | |
162 | |
143 | sprintf(data,"%s|%d|%s|%s|%d|%d|%ld", settings.meta_host, num_players, VERSION "+", |
163 | sprintf (data, "%s|%d|%s|%s|%d|%d|%ld", settings.meta_host, num_players, VERSION "+", |
144 | settings.meta_comment, cst_tot.ibytes, cst_tot.obytes, |
164 | settings.meta_comment, cst_tot.ibytes, cst_tot.obytes, (long) time (NULL) - cst_tot.time_start); |
145 | (long)time(NULL) - cst_tot.time_start); |
|
|
146 | if (sendto(metafd, data, strlen(data), 0, (struct sockaddr *)&sock, sizeof(sock))<0) { |
165 | if (sendto (metafd, data, strlen (data), 0, (struct sockaddr *) &sock, sizeof (sock)) < 0) |
|
|
166 | { |
147 | LOG(llevDebug,"metaserver_update: sendto failed, err = %d\n", errno); |
167 | LOG (llevDebug, "metaserver_update: sendto failed, err = %d\n", errno); |
148 | } |
168 | } |
149 | } |
169 | } |
150 | |
|
|