ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/metaserver.C
Revision: 1.5
Committed: Mon Oct 2 16:55:53 2006 UTC (17 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +0 -0 lines
State: FILE REMOVED
Log Message:
*** empty log message ***

File Contents

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