ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/metaserver.c
Revision: 1.10
Committed: Sun Aug 13 17:16:06 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +0 -0 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# Content
1 /*
2 * static char *rcsid_metaserver_c =
3 * "$Id$";
4 */
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 player *pl;
124
125 if (metafd == -1) return; /* No valid connection */
126
127 /* We could use socket_info.nconns, but that is not quite as accurate,
128 * as connections in the progress of being established, are listening
129 * 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
131 * players are not counted.
132 */
133 for (pl=first_player; pl!=NULL; pl=pl->next) {
134 if (pl->ob->map == NULL) continue;
135 if (pl->hidden) continue;
136 if (QUERY_FLAG(pl->ob, FLAG_WIZ)) continue;
137 if (QUERY_FLAG(pl->ob, FLAG_AFK)) continue;
138 if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) continue;
139 //if (pl->socket.is_bot) continue;
140 num_players++;
141 }
142
143 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,
145 (long)time(NULL) - cst_tot.time_start);
146 if (sendto(metafd, data, strlen(data), 0, (struct sockaddr *)&sock, sizeof(sock))<0) {
147 LOG(llevDebug,"metaserver_update: sendto failed, err = %d\n", errno);
148 }
149 }
150