ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/loop.C
(Generate patch)

Comparing deliantra/server/socket/loop.C (file contents):
Revision 1.3 by root, Tue Aug 29 08:01:38 2006 UTC vs.
Revision 1.9 by root, Tue Dec 12 20:53:03 2006 UTC

1
2/*
3 * static char *rcsid_loop_c =
4 * "$Id: loop.C,v 1.3 2006/08/29 08:01:38 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002-2003 Mark Wedel & The Crossfire Development Team 4 Copyright (C) 2002-2003 Mark Wedel & The Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The author can be reached via e-mail to crossfire-devel@real-time.com 21 The author can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29 23
30/** 24/**
31 * \file 25 * \file
32 * Main client/server loops. 26 * Main client/server loops.
39 */ 33 */
40 34
41 35
42#include <global.h> 36#include <global.h>
43#ifndef __CEXTRACT__ 37#ifndef __CEXTRACT__
44#include <sproto.h> 38# include <sproto.h>
45#include <sockproto.h> 39# include <sockproto.h>
46#endif 40#endif
47 41
48#ifndef WIN32 /* ---win32 exclude unix headers */
49#include <sys/types.h> 42#include <sys/types.h>
50#include <sys/time.h> 43#include <sys/time.h>
51#include <sys/socket.h> 44#include <sys/socket.h>
52#include <netinet/in.h> 45#include <netinet/in.h>
53#include <netdb.h> 46#include <netdb.h>
54#endif /* end win32 */
55 47
56#ifdef HAVE_UNISTD_H 48#ifdef HAVE_UNISTD_H
57#include <unistd.h> 49# include <unistd.h>
58#endif 50#endif
59 51
60#ifdef HAVE_ARPA_INET_H 52#ifdef HAVE_ARPA_INET_H
61#include <arpa/inet.h> 53# include <arpa/inet.h>
62#endif 54#endif
63 55
64#include <loader.h> 56#include <loader.h>
65#include <newserver.h> 57#include <newserver.h>
66 58
75 * before player joins, and those happen after the player has joined. 67 * before player joins, and those happen after the player has joined.
76 * As such, we have function types that might be called, so 68 * As such, we have function types that might be called, so
77 * we end up having 2 tables. 69 * we end up having 2 tables.
78 */ 70 */
79 71
80typedef void (*func_uint8_int_ns) (char*, int, NewSocket *); 72typedef void (*func_uint8_int_ns) (char *, int, NewSocket *);
81 73
82struct NsCmdMapping { 74struct NsCmdMapping
75{
83 const char *cmdname; 76 const char *cmdname;
84 func_uint8_int_ns cmdproc; 77 func_uint8_int_ns cmdproc;
85}; 78};
86 79
87typedef void (*func_uint8_int_pl)(char*, int, player *); 80typedef void (*func_uint8_int_pl) (char *, int, player *);
88struct PlCmdMapping { 81struct PlCmdMapping
82{
89 const char *cmdname; 83 const char *cmdname;
90 func_uint8_int_pl cmdproc; 84 func_uint8_int_pl cmdproc;
91 uint8 flag; 85 uint8 flag;
92}; 86};
93 87
94/** 88/**
95 * Dispatch table for the server. 89 * Dispatch table for the server.
96 * 90 *
103 * to cast it here instead of a bunch of times in the function itself. 97 * to cast it here instead of a bunch of times in the function itself.
104 * flag is 1 if the player must be in the playing state to issue the 98 * flag is 1 if the player must be in the playing state to issue the
105 * command, 0 if they can issue it at any time. 99 * command, 0 if they can issue it at any time.
106 */ 100 */
107static struct PlCmdMapping plcommands[] = { 101static struct PlCmdMapping plcommands[] = {
108 { "examine", ExamineCmd, 1}, 102 {"examine", ExamineCmd, 1},
109 { "apply", ApplyCmd, 1}, 103 {"apply", ApplyCmd, 1},
110 { "move", MoveCmd, 1}, 104 {"move", MoveCmd, 1},
111 { "reply", ReplyCmd, 0}, 105 {"reply", ReplyCmd, 0},
112 { "command", PlayerCmd, 1}, 106 {"command", PlayerCmd, 1},
113 { "ncom", (func_uint8_int_pl)NewPlayerCmd, 1}, 107 {"ncom", (func_uint8_int_pl) NewPlayerCmd, 1},
114 { "lookat", LookAt, 1}, 108 {"lookat", LookAt, 1},
115 { "lock", (func_uint8_int_pl)LockItem, 1}, 109 {"lock", (func_uint8_int_pl) LockItem, 1},
116 { "mark", (func_uint8_int_pl)MarkItem, 1}, 110 {"mark", (func_uint8_int_pl) MarkItem, 1},
117 { "mapredraw", MapRedrawCmd, 0}, /* Added: phil */ 111 {"mapredraw", MapRedrawCmd, 0}, /* Added: phil */
118 { "mapinfo", MapInfoCmd, 2}, /* CF+ */ 112 {"mapinfo", MapInfoCmd, 2}, /* CF+ */
119 { "ext", ExtCmd, 2}, /* CF+ */ 113 {"ext", ExtCmd, 2}, /* CF+ */
120 { NULL, NULL, 0} /* terminator */ 114 {NULL, NULL, 0} /* terminator */
121}; 115};
122 116
123/** Face-related commands */ 117/** Face-related commands */
124static struct NsCmdMapping nscommands[] = { 118static struct NsCmdMapping nscommands[] = {
125 { "addme", AddMeCmd }, 119 {"addme", AddMeCmd},
126 { "askface", SendFaceCmd}, /* Added: phil */ 120 {"askface", SendFaceCmd}, /* Added: phil */
127 { "requestinfo", RequestInfo}, 121 {"requestinfo", RequestInfo},
128 { "setfacemode", SetFaceMode}, 122 {"setfacemode", SetFaceMode},
129 { "setsound", SetSound}, 123 {"setsound", SetSound},
130 { "setup", SetUp}, 124 {"setup", SetUp},
131 { "version", VersionCmd }, 125 {"version", VersionCmd},
132 { "toggleextendedinfos", ToggleExtendedInfos}, /*Added: tchize*/ 126 {"toggleextendedinfos", ToggleExtendedInfos}, /*Added: tchize */
133 { "toggleextendedtext", ToggleExtendedText}, /*Added: tchize*/ 127 {"toggleextendedtext", ToggleExtendedText}, /*Added: tchize */
134 { "asksmooth", AskSmooth}, /*Added: tchize (smoothing technologies)*/ 128 {"asksmooth", AskSmooth}, /*Added: tchize (smoothing technologies) */
135 { NULL, NULL} /* terminator (I, II & III)*/ 129 {NULL, NULL} /* terminator (I, II & III) */
136}; 130};
137 131
138/** 132/**
139 * RequestInfo is sort of a meta command. There is some specific 133 * RequestInfo is sort of a meta command. There is some specific
140 * request of information, but we call other functions to provide 134 * request of information, but we call other functions to provide
141 * that information. 135 * that information.
142 */ 136 */
137void
143void RequestInfo(char *buf, int len, NewSocket *ns) 138RequestInfo (char *buf, int len, NewSocket * ns)
144{ 139{
145 char *params=NULL, *cp; 140 char *params = NULL, *cp;
141
146 /* No match */ 142 /* No match */
147 char bigbuf[MAX_BUF]; 143 char bigbuf[MAX_BUF];
148 int slen; 144 int slen;
149 145
150 /* Set up replyinfo before we modify any of the buffers - this is used 146 /* Set up replyinfo before we modify any of the buffers - this is used
151 * if we don't find a match. 147 * if we don't find a match.
152 */ 148 */
153 strcpy(bigbuf,"replyinfo "); 149 strcpy (bigbuf, "replyinfo ");
154 slen = strlen(bigbuf); 150 slen = strlen (bigbuf);
155 safe_strcat(bigbuf, buf, &slen, MAX_BUF); 151 safe_strcat (bigbuf, buf, &slen, MAX_BUF);
156 152
157 /* find the first space, make it null, and update the 153 /* find the first space, make it null, and update the
158 * params pointer. 154 * params pointer.
159 */ 155 */
160 for (cp = buf; *cp != '\0'; cp++) 156 for (cp = buf; *cp != '\0'; cp++)
161 if (*cp==' ') { 157 if (*cp == ' ')
158 {
162 *cp = '\0'; 159 *cp = '\0';
163 params = cp + 1; 160 params = cp + 1;
164 break; 161 break;
165 } 162 }
166 if (!strcmp(buf, "image_info")) send_image_info(ns, params); 163 if (!strcmp (buf, "image_info"))
167 else if (!strcmp(buf,"image_sums")) send_image_sums(ns, params); 164 send_image_info (ns, params);
168 else if (!strcmp(buf,"skill_info")) send_skill_info(ns, params); 165 else if (!strcmp (buf, "image_sums"))
169 else if (!strcmp(buf,"spell_paths")) send_spell_paths(ns, params); 166 send_image_sums (ns, params);
167 else if (!strcmp (buf, "skill_info"))
168 send_skill_info (ns, params);
169 else if (!strcmp (buf, "spell_paths"))
170 send_spell_paths (ns, params);
171 else
170 else Write_String_To_Socket(ns, bigbuf, len); 172 Write_String_To_Socket (ns, bigbuf, len);
171} 173}
172
173/**
174 * Handles old socket format.
175 */
176void Handle_Oldsocket(NewSocket *ns)
177{
178 int stat,i;
179 CommFunc command;
180 char buf[MAX_BUF],*cp;
181 object ob;
182 player pl;
183
184 /* This is not the most efficient block, but keeps the code simpler -
185 * we basically read a byte at a time until we get a newline, error,
186 * or no more characters to read.
187 */
188 do {
189 /* hack to disable old socket mode without creating too many conflicts */
190 if (1 || ns->inbuf.len >= MAXSOCKBUF-1) {
191 ns->status = Ns_Dead;
192 LOG(llevDebug, "Old input socket sent too much data without newline\n");
193 return;
194 }
195#ifdef WIN32 /* ***win32: change oldsocket read() to recv() */
196 stat = recv(ns->fd, ns->inbuf.buf + ns->inbuf.len, 1,0);
197
198 if (stat==-1 && WSAGetLastError() !=WSAEWOULDBLOCK) {
199#else
200 do {
201 stat = read(ns->fd, ns->inbuf.buf + ns->inbuf.len, 1);
202 } while ((stat<0) && (errno == EINTR));
203
204 if (stat<0 && errno != EAGAIN && errno !=EWOULDBLOCK) {
205#endif
206 LOG(llevError, "Cannot read from socket: %s\n", strerror_local(errno));
207 ns->status = Ns_Dead;
208 return;
209 }
210 if (stat == 0) return;
211 } while (ns->inbuf.buf[ns->inbuf.len++]!='\n');
212
213 ns->inbuf.buf[ns->inbuf.len]=0;
214
215 cp = strchr((const char*)ns->inbuf.buf, ' ');
216 if (cp) {
217 /* Replace the space with a null, skip any more spaces */
218 *cp++=0;
219 while (isspace(*cp)) cp++;
220 }
221
222 /* Strip off all spaces and control characters from end of line */
223 for (i=ns->inbuf.len-1; i>=0; i--) {
224 if (ns->inbuf.buf[i]<=32) ns->inbuf.buf[i]=0;
225 else break;
226 }
227 ns->inbuf.len=0; /* reset for next read */
228
229 /* If just a return, don't do anything */
230 if (ns->inbuf.buf[0] == 0) return;
231 if (!strcasecmp((const char*)ns->inbuf.buf,"quit")) {
232 ns->status = Ns_Dead;
233 return;
234 }
235 if (!strcasecmp((const char*)ns->inbuf.buf, "listen")) {
236 if (cp) {
237 char *buf="Socket switched to listen mode\n";
238
239 free(ns->comment);
240 ns->comment = strdup_local(cp);
241 ns->old_mode = Old_Listen;
242 cs_write_string(ns, buf, strlen(buf));
243 } else {
244 char *buf="Need to supply a comment/url to listen\n";
245 cs_write_string(ns, buf, strlen(buf));
246 }
247 return;
248 }
249 if (!strcasecmp((const char*)ns->inbuf.buf, "name")) {
250 char *cp1=NULL;
251 if (cp) cp1= strchr(cp, ' ');
252 if (cp1) {
253 *cp1++ = 0;
254 while (isspace(*cp1)) cp1++;
255 }
256 if (!cp || !cp1) {
257 char *buf="Need to provide a name/password to name\n";
258 cs_write_string(ns, buf, strlen(buf));
259 return;
260 }
261
262 if (verify_player(cp, cp1)==0) {
263 char *buf="Welcome back\n";
264 free(ns->comment);
265 ns->comment = strdup_local(cp);
266 ns->old_mode = Old_Player;
267 cs_write_string(ns, buf, strlen(buf));
268 }
269 else if (verify_player(cp, cp1)==2) {
270 ns->password_fails++;
271 if (ns->password_fails >= MAX_PASSWORD_FAILURES) {
272 char *buf="You failed to log in too many times, you will now be kicked.\n";
273 LOG(llevInfo, "A player connecting from %s in oldsocketmode has been dropped for password failure\n",
274 ns->host);
275 cs_write_string(ns, buf, strlen(buf));
276 ns->status = Ns_Dead;
277 }
278 else {
279 char *buf="Could not login you in. Check your name and password.\n";
280 cs_write_string(ns, buf, strlen(buf));
281 }
282 }
283 else {
284 char *buf="Could not login you in. Check your name and password.\n";
285 cs_write_string(ns, buf, strlen(buf));
286 }
287 return;
288 }
289
290 command = find_oldsocket_command((char*)ns->inbuf.buf);
291 if (!command && ns->old_mode==Old_Player) {
292 command = find_oldsocket_command2((char*)ns->inbuf.buf);
293 }
294 if (!command) {
295 snprintf(buf, sizeof(buf), "Could not find command: %s\n", ns->inbuf.buf);
296 cs_write_string(ns, buf, strlen(buf));
297 return;
298 }
299
300 /* This is a bit of a hack, but works. Basically, we make some
301 * fake object and player pointers and give at it.
302 * This works as long as the functions we are calling don't need
303 * to do anything to the object structure (ie, they are only
304 * outputting information and not actually updating anything much.)
305 */
306 ob.contr = &pl;
307 pl.ob = &ob;
308 ob.type = PLAYER;
309 pl.listening = 10;
310 pl.socket = *ns;
311 pl.outputs_count = 1;
312 ob.name = ns->comment;
313
314 command(&ob, cp);
315}
316
317 174
318/** 175/**
319 * Handle client input. 176 * Handle client input.
320 * 177 *
321 * HandleClient is actually not named really well - we only get here once 178 * HandleClient is actually not named really well - we only get here once
323 * sock is the output socket information. pl is the player associated 180 * sock is the output socket information. pl is the player associated
324 * with this socket, null if no player (one of the init_sockets for just 181 * with this socket, null if no player (one of the init_sockets for just
325 * starting a connection) 182 * starting a connection)
326 */ 183 */
327 184
185void
328void HandleClient(NewSocket *ns, player *pl) 186HandleClient (NewSocket * ns, player *pl)
329{ 187{
330 int len=0,i,cnt; 188 int len = 0, i, cnt;
331 char *data; 189 char *data;
332 190
333 /* Loop through this - maybe we have several complete packets here. */ 191 /* Loop through this - maybe we have several complete packets here. */
334 // limit to a few commands only, though, as to not monopolise the server 192 // limit to a few commands only, though, as to not monopolise the server
335 for (cnt = 16; cnt--; ) { 193 for (cnt = 16; cnt--;)
194 {
336 /* If it is a player, and they don't have any speed left, we 195 /* If it is a player, and they don't have any speed left, we
337 * return, and will read in the data when they do have time. 196 * return, and will read in the data when they do have time.
338 */ 197 */
339 if (pl && pl->state==ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0) { 198 if (pl && pl->state == ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0)
199 {
340 return; 200 return;
341 }
342 201 }
343 if (ns->status == Ns_Old) { 202
344 Handle_Oldsocket(ns);
345 return;
346 }
347 i=SockList_ReadPacket(ns->fd, &ns->inbuf, MAXSOCKBUF-1); 203 i = SockList_ReadPacket (ns->fd, &ns->inbuf, MAXSOCKBUF - 1);
348 /* Special hack - let the user switch to old mode if in the Ns_Add 204
349 * phase. Don't demand they add in the special length bytes 205 if (i < 0)
350 */
351 if (ns->status == Ns_Add) {
352 if (!strncasecmp((const char*)ns->inbuf.buf,"oldsocketmode", 13)) {
353 ns->status = Ns_Old;
354 ns->inbuf.len=0;
355 cs_write_string(ns, "Switched to old socket mode\n", 28);
356 LOG(llevDebug,"Switched socket to old socket mode\n");
357 return;
358 }
359 } 206 {
360
361 if (i<0) {
362#ifdef ESRV_DEBUG 207#ifdef ESRV_DEBUG
363 LOG(llevDebug,"HandleClient: Read error on connection player %s\n", (pl?pl->ob->name:"None")); 208 LOG (llevDebug, "HandleClient: Read error on connection player %s\n", (pl ? pl->ob->name : "None"));
364#endif 209#endif
365 /* Caller will take care of cleaning this up */ 210 /* Caller will take care of cleaning this up */
366 ns->status =Ns_Dead; 211 ns->status = Ns_Dead;
367 return; 212 return;
368 } 213 }
369 /* Still dont have a full packet */ 214 /* Still dont have a full packet */
215 if (i == 0)
370 if (i==0) return; 216 return;
371 217
372// //D//TODO//temporarily log long commands 218// //D//TODO//temporarily log long commands
373// if (ns->inbuf.len >= 40 && pl && pl->ob) 219// if (ns->inbuf.len >= 40 && pl && pl->ob)
374// LOG (llevDebug, "HandleClient: long comamnd from <%s,%s> %d<%s>\n", pl->ob->name, ns->host, ns->inbuf.len, ns->inbuf.buf + 2); 220// LOG (llevDebug, "HandleClient: long comamnd from <%s,%s> %d<%s>\n", pl->ob->name, ns->host, ns->inbuf.len, ns->inbuf.buf + 2);
375 221
376 /* First, break out beginning word. There are at least 222 /* First, break out beginning word. There are at least
377 * a few commands that do not have any paremeters. If 223 * a few commands that do not have any paremeters. If
378 * we get such a command, don't worry about trying 224 * we get such a command, don't worry about trying
379 * to break it up. 225 * to break it up.
380 */ 226 */
381 data = (char *)strchr((char*)ns->inbuf.buf +2, ' '); 227 data = (char *) strchr ((char *) ns->inbuf.buf + 2, ' ');
382 if (data) { 228 if (data)
229 {
383 *data='\0'; 230 *data = '\0';
384 data++; 231 data++;
385 len = ns->inbuf.len - (data - (char*)ns->inbuf.buf); 232 len = ns->inbuf.len - (data - (char *) ns->inbuf.buf);
386 } 233 }
234 else
387 else len=0; 235 len = 0;
388 236
389 ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ 237 ns->inbuf.buf[ns->inbuf.len] = '\0'; /* Terminate buffer - useful for string data */
390 for (i=0; nscommands[i].cmdname !=NULL; i++) { 238 for (i = 0; nscommands[i].cmdname != NULL; i++)
239 {
391 if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) { 240 if (strcmp ((char *) ns->inbuf.buf + 2, nscommands[i].cmdname) == 0)
241 {
392 nscommands[i].cmdproc((char*)data,len,ns); 242 nscommands[i].cmdproc ((char *) data, len, ns);
393 ns->inbuf.len=0; 243 ns->inbuf.len = 0;
394 return;//D// not doing this causes random memory corruption 244 return; //D// not doing this causes random memory corruption
395 goto next_packet; 245 goto next_packet;
396 }
397 } 246 }
247 }
398 /* Player must be in the playing state or the flag on the 248 /* Player must be in the playing state or the flag on the
399 * the command must be zero for the user to use the command - 249 * the command must be zero for the user to use the command -
400 * otherwise, a player cam save, be in the play_again state, and 250 * otherwise, a player cam save, be in the play_again state, and
401 * the map they were on gets swapped out, yet things that try to look 251 * the map they were on gets swapped out, yet things that try to look
402 * at the map causes a crash. If the command is valid, but 252 * at the map causes a crash. If the command is valid, but
403 * one they can't use, we still swallow it up. 253 * one they can't use, we still swallow it up.
404 */ 254 */
255 if (pl)
405 if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) { 256 for (i = 0; plcommands[i].cmdname != NULL; i++)
257 {
406 if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) { 258 if (strcmp ((char *) ns->inbuf.buf + 2, plcommands[i].cmdname) == 0)
259 {
407 if (pl->state == ST_PLAYING || !(plcommands[i].flag & 1)) 260 if (pl->state == ST_PLAYING || !(plcommands[i].flag & 1))
408 plcommands[i].cmdproc((char*)data,len,pl); 261 plcommands[i].cmdproc ((char *) data, len, pl);
409 ns->inbuf.len=0; 262 ns->inbuf.len = 0;
410 //D// not doing this causes random memory corruption 263 //D// not doing this causes random memory corruption
411 if (plcommands[i].flag & 2) 264 if (plcommands[i].flag & 2)
412 goto next_packet; 265 goto next_packet;
413 return; 266 return;
414 } 267 }
415 } 268 }
416 /* If we get here, we didn't find a valid command. Logging 269 /* If we get here, we didn't find a valid command. Logging
417 * this might be questionable, because a broken client/malicious 270 * this might be questionable, because a broken client/malicious
418 * user could certainly send a whole bunch of invalid commands. 271 * user could certainly send a whole bunch of invalid commands.
419 */ 272 */
420 LOG(llevDebug,"Bad command from client (%s)\n",ns->inbuf.buf+2); 273 LOG (llevDebug, "Bad command from client (%s)\n", ns->inbuf.buf + 2);
421 next_packet: 274 next_packet:
422 ; 275 ;
423 } 276 }
424} 277}
425 278
426 279
427/***************************************************************************** 280/*****************************************************************************
430 * sending. 283 * sending.
431 * 284 *
432 ******************************************************************************/ 285 ******************************************************************************/
433 286
434#ifdef WATCHDOG 287#ifdef WATCHDOG
288
435/** 289/**
436 * Tell watchdog that we are still alive 290 * Tell watchdog that we are still alive
437 * 291 *
438 * I put the function here since we should hopefully already be getting 292 * I put the function here since we should hopefully already be getting
439 * all the needed include files for socket support 293 * all the needed include files for socket support
440 */ 294 */
441 295
296void
442void watchdog(void) 297watchdog (void)
443{ 298{
444 static int fd=-1; 299 static int fd = -1;
445 static struct sockaddr_in insock; 300 static struct sockaddr_in insock;
446 301
447 if (fd==-1) 302 if (fd == -1)
448 { 303 {
449 struct protoent *protoent; 304 struct protoent *protoent;
450 305
451 if ((protoent=getprotobyname("udp"))==NULL || 306 if ((protoent = getprotobyname ("udp")) == NULL || (fd = socket (PF_INET, SOCK_DGRAM, protoent->p_proto)) == -1)
452 (fd=socket(PF_INET, SOCK_DGRAM, protoent->p_proto))==-1)
453 { 307 {
454 return; 308 return;
455 } 309 }
456 insock.sin_family=AF_INET; 310 insock.sin_family = AF_INET;
457 insock.sin_port=htons((unsigned short)13325); 311 insock.sin_port = htons ((unsigned short) 13325);
458 insock.sin_addr.s_addr=inet_addr("127.0.0.1"); 312 insock.sin_addr.s_addr = inet_addr ("127.0.0.1");
459 } 313 }
460 sendto(fd,(void *)&fd,1,0,(struct sockaddr *)&insock,sizeof(insock)); 314 sendto (fd, (void *) &fd, 1, 0, (struct sockaddr *) &insock, sizeof (insock));
461} 315}
462#endif 316#endif
463 317
318void
464void flush_sockets(void) 319flush_sockets (void)
465{ 320{
466 player *pl; 321 player *pl;
467 322
468 for (pl = first_player; pl != NULL; pl = pl->next) 323 for (pl = first_player; pl != NULL; pl = pl->next)
469 if (pl->socket.status != Ns_Dead) 324 if (pl->socket.status != Ns_Dead)
475 * 330 *
476 * A bit of this code is grabbed out of socket.c 331 * A bit of this code is grabbed out of socket.c
477 * There are 2 lists we need to look through - init_sockets is a list 332 * There are 2 lists we need to look through - init_sockets is a list
478 * 333 *
479 */ 334 */
335void
480void doeric_server(void) 336doeric_server (void)
481{ 337{
482 int i, pollret; 338 int i, pollret;
483 fd_set tmp_read, tmp_exceptions, tmp_write; 339 fd_set tmp_read, tmp_exceptions, tmp_write;
484 struct sockaddr_in addr; 340 struct sockaddr_in addr;
485 socklen_t addrlen=sizeof(struct sockaddr); 341 socklen_t addrlen = sizeof (struct sockaddr);
486 player *pl, *next; 342 player *pl, *next;
487 343
488#ifdef CS_LOGSTATS 344#ifdef CS_LOGSTATS
489 if ((time(NULL)-cst_lst.time_start)>=CS_LOGTIME) 345 if ((time (NULL) - cst_lst.time_start) >= CS_LOGTIME)
490 write_cs_stats(); 346 write_cs_stats ();
491#endif 347#endif
492 348
493 FD_ZERO(&tmp_read); 349 FD_ZERO (&tmp_read);
494 FD_ZERO(&tmp_write); 350 FD_ZERO (&tmp_write);
495 FD_ZERO(&tmp_exceptions); 351 FD_ZERO (&tmp_exceptions);
496 352
497 for(i=0;i<socket_info.allocated_sockets;i++) { 353 for (i = 0; i < socket_info.allocated_sockets; i++)
354 {
498 if (init_sockets[i].status == Ns_Dead) { 355 if (init_sockets[i].status == Ns_Dead)
356 {
499 free_newsocket(&init_sockets[i]); 357 free_newsocket (&init_sockets[i]);
500 init_sockets[i].status = Ns_Avail; 358 init_sockets[i].status = Ns_Avail;
501 socket_info.nconns--; 359 socket_info.nconns--;
360 }
502 } else if (init_sockets[i].status != Ns_Avail){ 361 else if (init_sockets[i].status != Ns_Avail)
362 {
503 FD_SET((uint32)init_sockets[i].fd, &tmp_read); 363 FD_SET ((uint32) init_sockets[i].fd, &tmp_read);
504 FD_SET((uint32)init_sockets[i].fd, &tmp_write); 364 FD_SET ((uint32) init_sockets[i].fd, &tmp_write);
505 FD_SET((uint32)init_sockets[i].fd, &tmp_exceptions); 365 FD_SET ((uint32) init_sockets[i].fd, &tmp_exceptions);
506 } 366 }
507 } 367 }
508 368
509 /* Go through the players. Let the loop set the next pl value, 369 /* Go through the players. Let the loop set the next pl value,
510 * since we may remove some 370 * since we may remove some
511 */ 371 */
512 for (pl=first_player; pl!=NULL; ) { 372 for (pl = first_player; pl != NULL;)
373 {
513 if (pl->socket.status == Ns_Dead) { 374 if (pl->socket.status == Ns_Dead)
375 {
514 player *npl=pl->next; 376 player *npl = pl->next;
515 377
516 save_player(pl->ob, 0); 378 save_player (pl->ob, 0);
517 if(!QUERY_FLAG(pl->ob,FLAG_REMOVED)) { 379 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
380 {
518 terminate_all_pets(pl->ob); 381 terminate_all_pets (pl->ob);
519 remove_ob(pl->ob); 382 pl->ob->remove ();
520 } 383 }
521 leave(pl,1); 384 leave (pl, 1);
522 final_free_player(pl); 385 final_free_player (pl);
523 pl=npl; 386 pl = npl;
387 }
388 else
524 } 389 {
525 else {
526 FD_SET((uint32)pl->socket.fd, &tmp_read); 390 FD_SET ((uint32) pl->socket.fd, &tmp_read);
527 FD_SET((uint32)pl->socket.fd, &tmp_write); 391 FD_SET ((uint32) pl->socket.fd, &tmp_write);
528 FD_SET((uint32)pl->socket.fd, &tmp_exceptions); 392 FD_SET ((uint32) pl->socket.fd, &tmp_exceptions);
529 pl=pl->next; 393 pl = pl->next;
530 } 394 }
531 } 395 }
532 396
533 /* Reset timeout each time, since some OS's will change the values on 397 /* Reset timeout each time, since some OS's will change the values on
534 * the return from select. 398 * the return from select.
535 */ 399 */
536 socket_info.timeout.tv_sec = 0; 400 socket_info.timeout.tv_sec = 0;
537 socket_info.timeout.tv_usec = 0; 401 socket_info.timeout.tv_usec = 0;
538 402
539 pollret= select(socket_info.max_filedescriptor, &tmp_read, &tmp_write, 403 pollret = select (socket_info.max_filedescriptor, &tmp_read, &tmp_write, &tmp_exceptions, &socket_info.timeout);
540 &tmp_exceptions, &socket_info.timeout);
541 404
542 if (pollret==-1) { 405 if (pollret == -1)
406 {
543 LOG(llevError, "select failed: %s\n", strerror_local(errno)); 407 LOG (llevError, "select failed: %s\n", strerror (errno));
544 return; 408 return;
545 } 409 }
546 410
547 /* We need to do some of the processing below regardless */ 411 /* We need to do some of the processing below regardless */
412
548/* if (!pollret) return;*/ 413/* if (!pollret) return;*/
549 414
550 /* Following adds a new connection */ 415 /* Following adds a new connection */
551 if (pollret && FD_ISSET(init_sockets[0].fd, &tmp_read)) { 416 if (pollret && FD_ISSET (init_sockets[0].fd, &tmp_read))
417 {
552 int newsocknum=0; 418 int newsocknum = 0;
553 419
554#ifdef ESRV_DEBUG 420#ifdef ESRV_DEBUG
555 LOG(llevDebug,"doeric_server: New Connection\n"); 421 LOG (llevDebug, "doeric_server: New Connection\n");
556#endif 422#endif
557 /* If this is the case, all sockets currently in used */ 423 /* If this is the case, all sockets currently in used */
558 if (socket_info.allocated_sockets <= socket_info.nconns) { 424 if (socket_info.allocated_sockets <= socket_info.nconns)
425 {
559 init_sockets = (NewSocket *) realloc(init_sockets,sizeof(NewSocket)*(socket_info.nconns+1)); 426 init_sockets = (NewSocket *) realloc (init_sockets, sizeof (NewSocket) * (socket_info.nconns + 1));
427 if (!init_sockets)
560 if (!init_sockets) fatal(OUT_OF_MEMORY); 428 fatal (OUT_OF_MEMORY);
561 newsocknum = socket_info.allocated_sockets; 429 newsocknum = socket_info.allocated_sockets;
562 socket_info.allocated_sockets++; 430 socket_info.allocated_sockets++;
563 init_sockets[newsocknum].faces_sent_len = nrofpixmaps; 431 init_sockets[newsocknum].faces_sent_len = nrofpixmaps;
564 init_sockets[newsocknum].faces_sent = (uint8*) malloc(nrofpixmaps*sizeof(*init_sockets[newsocknum].faces_sent)); 432 init_sockets[newsocknum].faces_sent = (uint8 *) malloc (nrofpixmaps * sizeof (*init_sockets[newsocknum].faces_sent));
565 if (!init_sockets[newsocknum].faces_sent) fatal(OUT_OF_MEMORY); 433 if (!init_sockets[newsocknum].faces_sent)
434 fatal (OUT_OF_MEMORY);
566 init_sockets[newsocknum].status = Ns_Avail; 435 init_sockets[newsocknum].status = Ns_Avail;
436 }
437 else
567 } 438 {
568 else {
569 int j; 439 int j;
570 440
571 for (j=1; j<socket_info.allocated_sockets; j++) 441 for (j = 1; j < socket_info.allocated_sockets; j++)
572 if (init_sockets[j].status == Ns_Avail) { 442 if (init_sockets[j].status == Ns_Avail)
443 {
573 newsocknum=j; 444 newsocknum = j;
574 break; 445 break;
575 } 446 }
576 } 447 }
577 init_sockets[newsocknum].fd=accept(init_sockets[0].fd, (struct sockaddr *)&addr, &addrlen); 448 init_sockets[newsocknum].fd = accept (init_sockets[0].fd, (struct sockaddr *) &addr, &addrlen);
578 if (init_sockets[newsocknum].fd==-1) { 449 if (init_sockets[newsocknum].fd == -1)
450 {
579 LOG(llevError, "accept failed: %s\n", strerror_local(errno)); 451 LOG (llevError, "accept failed: %s\n", strerror (errno));
452 }
453 else
580 } 454 {
581 else {
582 char buf[MAX_BUF]; 455 char buf[MAX_BUF];
583 long ip; 456 long ip;
584 NewSocket *ns; 457 NewSocket *ns;
585 458
586 ns = &init_sockets[newsocknum]; 459 ns = &init_sockets[newsocknum];
587 460
588 ip = ntohl(addr.sin_addr.s_addr); 461 ip = ntohl (addr.sin_addr.s_addr);
589 sprintf(buf, "%ld.%ld.%ld.%ld", (ip>>24)&255, (ip>>16)&255, (ip>>8)&255, ip&255); 462 sprintf (buf, "%ld.%ld.%ld.%ld", (ip >> 24) & 255, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
590 463
591 if (checkbanned(NULL, buf)) { 464 if (checkbanned (NULL, buf))
465 {
592 LOG(llevInfo, "Banned host tried to connect: [%s]\n", buf); 466 LOG (llevInfo, "Banned host tried to connect: [%s]\n", buf);
593 close(init_sockets[newsocknum].fd); 467 close (init_sockets[newsocknum].fd);
594 init_sockets[newsocknum].fd = -1; 468 init_sockets[newsocknum].fd = -1;
469 }
470 else
595 } 471 {
596 else {
597 InitConnection(ns, buf); 472 InitConnection (ns, buf);
598 socket_info.nconns++; 473 socket_info.nconns++;
599 }
600 } 474 }
475 }
601 } 476 }
602 477
603 /* Check for any exceptions/input on the sockets */ 478 /* Check for any exceptions/input on the sockets */
479 if (pollret)
604 if (pollret) for(i=1;i<socket_info.allocated_sockets;i++) { 480 for (i = 1; i < socket_info.allocated_sockets; i++)
481 {
605 if (init_sockets[i].status == Ns_Avail) continue; 482 if (init_sockets[i].status == Ns_Avail)
483 continue;
606 if (FD_ISSET(init_sockets[i].fd,&tmp_exceptions)) { 484 if (FD_ISSET (init_sockets[i].fd, &tmp_exceptions))
485 {
607 free_newsocket(&init_sockets[i]); 486 free_newsocket (&init_sockets[i]);
608 init_sockets[i].status = Ns_Avail; 487 init_sockets[i].status = Ns_Avail;
609 socket_info.nconns--; 488 socket_info.nconns--;
610 continue; 489 continue;
611 } 490 }
612 if (FD_ISSET(init_sockets[i].fd, &tmp_read)) { 491 if (FD_ISSET (init_sockets[i].fd, &tmp_read))
492 {
613 HandleClient(&init_sockets[i], NULL); 493 HandleClient (&init_sockets[i], NULL);
614 } 494 }
615 if (FD_ISSET(init_sockets[i].fd, &tmp_write)) { 495 if (FD_ISSET (init_sockets[i].fd, &tmp_write))
496 {
616 init_sockets[i].can_write=1; 497 init_sockets[i].can_write = 1;
617 } 498 }
618 } 499 }
619 500
620 /* This does roughly the same thing, but for the players now */ 501 /* This does roughly the same thing, but for the players now */
621 for (pl=first_player; pl!=NULL; pl=next) { 502 for (pl = first_player; pl != NULL; pl = next)
503 {
622 504
623 next=pl->next; 505 next = pl->next;
624 if (pl->socket.status==Ns_Dead) continue; 506 if (pl->socket.status == Ns_Dead)
507 continue;
625 508
626 if (FD_ISSET(pl->socket.fd,&tmp_write)) { 509 if (FD_ISSET (pl->socket.fd, &tmp_write))
510 {
627 if (!pl->socket.can_write) { 511 if (!pl->socket.can_write)
512 {
628#if 0 513#if 0
629 LOG(llevDebug,"Player %s socket now write enabled\n", pl->ob->name); 514 LOG (llevDebug, "Player %s socket now write enabled\n", pl->ob->name);
630#endif 515#endif
631 pl->socket.can_write=1; 516 pl->socket.can_write = 1;
632 write_socket_buffer(&pl->socket); 517 write_socket_buffer (&pl->socket);
633 } 518 }
634 /* if we get an error on the write_socket buffer, no reason to 519 /* if we get an error on the write_socket buffer, no reason to
635 * continue on this socket. 520 * continue on this socket.
636 */ 521 */
637 if (pl->socket.status==Ns_Dead) continue; 522 if (pl->socket.status == Ns_Dead)
523 continue;
638 } 524 }
525 else
639 else pl->socket.can_write=0; 526 pl->socket.can_write = 0;
640 527
641 if (FD_ISSET(pl->socket.fd,&tmp_exceptions)) { 528 if (FD_ISSET (pl->socket.fd, &tmp_exceptions))
529 {
642 save_player(pl->ob, 0); 530 save_player (pl->ob, 0);
643 if(!QUERY_FLAG(pl->ob,FLAG_REMOVED)) { 531 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
532 {
644 terminate_all_pets(pl->ob); 533 terminate_all_pets (pl->ob);
645 remove_ob(pl->ob); 534 pl->ob->remove ();
646 } 535 }
647 leave(pl,1); 536 leave (pl, 1);
648 final_free_player(pl); 537 final_free_player (pl);
538 }
539 else
649 } 540 {
650 else {
651 HandleClient(&pl->socket, pl); 541 HandleClient (&pl->socket, pl);
652 /* If the player has left the game, then the socket status 542 /* If the player has left the game, then the socket status
653 * will be set to this be the leave function. We don't 543 * will be set to this be the leave function. We don't
654 * need to call leave again, as it has already been called 544 * need to call leave again, as it has already been called
655 * once. 545 * once.
656 */ 546 */
657 if (pl->socket.status==Ns_Dead) { 547 if (pl->socket.status == Ns_Dead)
548 {
658 save_player(pl->ob, 0); 549 save_player (pl->ob, 0);
659 if(!QUERY_FLAG(pl->ob,FLAG_REMOVED)) { 550 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
551 {
660 terminate_all_pets(pl->ob); 552 terminate_all_pets (pl->ob);
661 remove_ob(pl->ob); 553 pl->ob->remove ();
662 } 554 }
663 leave(pl,1); 555 leave (pl, 1);
664 final_free_player(pl); 556 final_free_player (pl);
557 }
665 } else { 558 else
559 {
666 560
667 /* Update the players stats once per tick. More efficient than 561 /* Update the players stats once per tick. More efficient than
668 * sending them whenever they change, and probably just as useful 562 * sending them whenever they change, and probably just as useful
669 */ 563 */
670 esrv_update_stats(pl); 564 esrv_update_stats (pl);
671 if (pl->last_weight != -1 && pl->last_weight != WEIGHT(pl->ob)) { 565 if (pl->last_weight != -1 && pl->last_weight != WEIGHT (pl->ob))
566 {
672 esrv_update_item(UPD_WEIGHT, pl->ob, pl->ob); 567 esrv_update_item (UPD_WEIGHT, pl->ob, pl->ob);
673 if(pl->last_weight != WEIGHT(pl->ob)) 568 if (pl->last_weight != WEIGHT (pl->ob))
674 LOG(llevError, "esrv_update_item(UPD_WEIGHT) did not set player weight: is %lu, should be %lu\n", (unsigned long)pl->last_weight, WEIGHT(pl->ob)); 569 LOG (llevError, "esrv_update_item(UPD_WEIGHT) did not set player weight: is %lu, should be %lu\n",
570 (unsigned long) pl->last_weight, WEIGHT (pl->ob));
675 } 571 }
676 /* draw_client_map does sanity checking that map is 572 /* draw_client_map does sanity checking that map is
677 * valid, so don't do it here. 573 * valid, so don't do it here.
678 */ 574 */
679 draw_client_map(pl->ob); 575 draw_client_map (pl->ob);
680 if (pl->socket.update_look) esrv_draw_look(pl->ob); 576 if (pl->socket.update_look)
577 esrv_draw_look (pl->ob);
681 } 578 }
682 } 579 }
683 } 580 }
684} 581}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines