ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/metaserver.c
Revision: 1.6
Committed: Tue Jul 11 10:35:20 2006 UTC (17 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +1 -1 lines
Log Message:
shop.c: Cheaper is actually better.
metaserver.c: correct usercount is actually better.

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *rcsid_metaserver_c =
3 root 1.2 * "$Id$";
4 root 1.1 */
5    
6     /*
7     CrossFire, A Multiplayer game for X-windows
8    
9     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10     Copyright (C) 1992 Frank Tore Johansen
11    
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16    
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     GNU General Public License for more details.
21    
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25    
26     The authors can be reached via e-mail at crossfire-devel@real-time.com
27     */
28    
29     /**
30     * \file
31     * \date 2003-12-02
32     * Meta-server related functions.
33     */
34    
35     #include <global.h>
36    
37     #ifndef WIN32 /* ---win32 exclude unix header files */
38     #include <sys/types.h>
39     #include <sys/socket.h>
40     #include <netinet/in.h>
41     #include <netdb.h>
42     #include <arpa/inet.h>
43    
44     #endif /* end win32 */
45    
46     static int metafd=-1;
47     static struct sockaddr_in sock;
48    
49     /**
50     * Connects to metaserver.
51     *
52     * Its only called once. If we are not
53     * 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     * that can be examined to at least see what the user was trying to do.
56     */
57     void metaserver_init(void)
58     {
59    
60     #ifdef WIN32 /* ***win32 metaserver_init(): init win32 socket */
61     struct hostent *hostbn;
62     int temp = 1;
63     #endif
64    
65     if (!settings.meta_on) {
66     metafd=-1;
67     return;
68     }
69    
70     if (isdigit(settings.meta_server[0]))
71     sock.sin_addr.s_addr = inet_addr(settings.meta_server);
72     else {
73     struct hostent *hostbn = gethostbyname(settings.meta_server);
74     if (hostbn == NULL) {
75     LOG(llevDebug,"metaserver_init: Unable to resolve hostname %s\n", settings.meta_server);
76     return;
77     }
78     memcpy(&sock.sin_addr, hostbn->h_addr, hostbn->h_length);
79     }
80     #ifdef WIN32 /* ***win32 metaserver_init(): init win32 socket */
81     ioctlsocket(metafd, FIONBIO , &temp);
82     #else
83     fcntl(metafd, F_SETFL, O_NONBLOCK);
84     #endif
85     if ((metafd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
86     LOG(llevDebug,"metaserver_init: Unable to create socket, err %d\n", errno);
87     return;
88     }
89     sock.sin_family = AF_INET;
90     sock.sin_port = htons(settings.meta_port);
91    
92     /* No hostname specified, so lets try to figure one out */
93     if (settings.meta_host[0]==0) {
94     char hostname[MAX_BUF], domain[MAX_BUF];
95     if (gethostname(hostname, MAX_BUF-1)) {
96     LOG(llevDebug,"metaserver_init: gethostname failed - will not report hostname\n");
97     return;
98     }
99    
100     #ifdef WIN32 /* ***win32 metaserver_init(): gethostbyname! */
101     hostbn = gethostbyname(hostname);
102     if (hostbn != (struct hostent *) NULL) /* quick hack */
103     memcpy(domain, hostbn->h_addr, hostbn->h_length);
104    
105     if (hostbn == (struct hostent *) NULL) {
106     #else
107     if (getdomainname(domain, MAX_BUF-1)) {
108     #endif /* win32 */
109     LOG(llevDebug,"metaserver_init: getdomainname failed - will not report hostname\n");
110     return;
111     }
112     /* Potential overrun here but unlikely to occur */
113     sprintf(settings.meta_host,"%s.%s", hostname, domain);
114     }
115     }
116    
117     /**
118     * Updates our info in the metaserver
119     */
120     void metaserver_update(void)
121     {
122     char data[MAX_BUF], num_players=0;
123 root 1.2 #define CAT2_SUXX
124     #ifdef CAT2_SUXX
125 root 1.4 num_players += 20;
126 root 1.2 #endif
127 root 1.1 player *pl;
128    
129     if (metafd == -1) return; /* No valid connection */
130    
131     /* We could use socket_info.nconns, but that is not quite as accurate,
132     * as connections in the progress of being established, are listening
133     * but don't have a player, etc. This operation below should not be that
134     * costly.
135     */
136 root 1.5 for (pl=first_player; pl!=NULL; pl=pl->next)
137 root 1.6 if (!pl->hidden && pl->ob->map) num_players++;
138 root 1.1
139 elmex 1.3 sprintf(data,"%s|%d|%s|%s|%d|%d|%ld", settings.meta_host, num_players, VERSION "+",
140 root 1.1 settings.meta_comment, cst_tot.ibytes, cst_tot.obytes,
141     (long)time(NULL) - cst_tot.time_start);
142     if (sendto(metafd, data, strlen(data), 0, (struct sockaddr *)&sock, sizeof(sock))<0) {
143     LOG(llevDebug,"metaserver_update: sendto failed, err = %d\n", errno);
144     }
145     }
146