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.5 by root, Sat Sep 9 21:48:29 2006 UTC vs.
Revision 1.7 by root, Thu Sep 14 22:34:05 2006 UTC

1
2/*
3 * static char *rcsid_loop_c =
4 * "$Id: loop.C,v 1.5 2006/09/09 21:48:29 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 */ 42#ifndef WIN32 /* ---win32 exclude unix headers */
49#include <sys/types.h> 43# include <sys/types.h>
50#include <sys/time.h> 44# include <sys/time.h>
51#include <sys/socket.h> 45# include <sys/socket.h>
52#include <netinet/in.h> 46# include <netinet/in.h>
53#include <netdb.h> 47# include <netdb.h>
54#endif /* end win32 */ 48#endif /* end win32 */
55 49
56#ifdef HAVE_UNISTD_H 50#ifdef HAVE_UNISTD_H
57#include <unistd.h> 51# include <unistd.h>
58#endif 52#endif
59 53
60#ifdef HAVE_ARPA_INET_H 54#ifdef HAVE_ARPA_INET_H
61#include <arpa/inet.h> 55# include <arpa/inet.h>
62#endif 56#endif
63 57
64#include <loader.h> 58#include <loader.h>
65#include <newserver.h> 59#include <newserver.h>
66 60
75 * before player joins, and those happen after the player has joined. 69 * before player joins, and those happen after the player has joined.
76 * As such, we have function types that might be called, so 70 * As such, we have function types that might be called, so
77 * we end up having 2 tables. 71 * we end up having 2 tables.
78 */ 72 */
79 73
80typedef void (*func_uint8_int_ns) (char*, int, NewSocket *); 74typedef void (*func_uint8_int_ns) (char *, int, NewSocket *);
81 75
82struct NsCmdMapping { 76struct NsCmdMapping
77{
83 const char *cmdname; 78 const char *cmdname;
84 func_uint8_int_ns cmdproc; 79 func_uint8_int_ns cmdproc;
85}; 80};
86 81
87typedef void (*func_uint8_int_pl)(char*, int, player *); 82typedef void (*func_uint8_int_pl) (char *, int, player *);
88struct PlCmdMapping { 83struct PlCmdMapping
84{
89 const char *cmdname; 85 const char *cmdname;
90 func_uint8_int_pl cmdproc; 86 func_uint8_int_pl cmdproc;
91 uint8 flag; 87 uint8 flag;
92}; 88};
93 89
94/** 90/**
95 * Dispatch table for the server. 91 * Dispatch table for the server.
96 * 92 *
103 * to cast it here instead of a bunch of times in the function itself. 99 * 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 100 * 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. 101 * command, 0 if they can issue it at any time.
106 */ 102 */
107static struct PlCmdMapping plcommands[] = { 103static struct PlCmdMapping plcommands[] = {
108 { "examine", ExamineCmd, 1}, 104 {"examine", ExamineCmd, 1},
109 { "apply", ApplyCmd, 1}, 105 {"apply", ApplyCmd, 1},
110 { "move", MoveCmd, 1}, 106 {"move", MoveCmd, 1},
111 { "reply", ReplyCmd, 0}, 107 {"reply", ReplyCmd, 0},
112 { "command", PlayerCmd, 1}, 108 {"command", PlayerCmd, 1},
113 { "ncom", (func_uint8_int_pl)NewPlayerCmd, 1}, 109 {"ncom", (func_uint8_int_pl) NewPlayerCmd, 1},
114 { "lookat", LookAt, 1}, 110 {"lookat", LookAt, 1},
115 { "lock", (func_uint8_int_pl)LockItem, 1}, 111 {"lock", (func_uint8_int_pl) LockItem, 1},
116 { "mark", (func_uint8_int_pl)MarkItem, 1}, 112 {"mark", (func_uint8_int_pl) MarkItem, 1},
117 { "mapredraw", MapRedrawCmd, 0}, /* Added: phil */ 113 {"mapredraw", MapRedrawCmd, 0}, /* Added: phil */
118 { "mapinfo", MapInfoCmd, 2}, /* CF+ */ 114 {"mapinfo", MapInfoCmd, 2}, /* CF+ */
119 { "ext", ExtCmd, 2}, /* CF+ */ 115 {"ext", ExtCmd, 2}, /* CF+ */
120 { NULL, NULL, 0} /* terminator */ 116 {NULL, NULL, 0} /* terminator */
121}; 117};
122 118
123/** Face-related commands */ 119/** Face-related commands */
124static struct NsCmdMapping nscommands[] = { 120static struct NsCmdMapping nscommands[] = {
125 { "addme", AddMeCmd }, 121 {"addme", AddMeCmd},
126 { "askface", SendFaceCmd}, /* Added: phil */ 122 {"askface", SendFaceCmd}, /* Added: phil */
127 { "requestinfo", RequestInfo}, 123 {"requestinfo", RequestInfo},
128 { "setfacemode", SetFaceMode}, 124 {"setfacemode", SetFaceMode},
129 { "setsound", SetSound}, 125 {"setsound", SetSound},
130 { "setup", SetUp}, 126 {"setup", SetUp},
131 { "version", VersionCmd }, 127 {"version", VersionCmd},
132 { "toggleextendedinfos", ToggleExtendedInfos}, /*Added: tchize*/ 128 {"toggleextendedinfos", ToggleExtendedInfos}, /*Added: tchize */
133 { "toggleextendedtext", ToggleExtendedText}, /*Added: tchize*/ 129 {"toggleextendedtext", ToggleExtendedText}, /*Added: tchize */
134 { "asksmooth", AskSmooth}, /*Added: tchize (smoothing technologies)*/ 130 {"asksmooth", AskSmooth}, /*Added: tchize (smoothing technologies) */
135 { NULL, NULL} /* terminator (I, II & III)*/ 131 {NULL, NULL} /* terminator (I, II & III) */
136}; 132};
137 133
138/** 134/**
139 * RequestInfo is sort of a meta command. There is some specific 135 * RequestInfo is sort of a meta command. There is some specific
140 * request of information, but we call other functions to provide 136 * request of information, but we call other functions to provide
141 * that information. 137 * that information.
142 */ 138 */
139void
143void RequestInfo(char *buf, int len, NewSocket *ns) 140RequestInfo (char *buf, int len, NewSocket * ns)
144{ 141{
145 char *params=NULL, *cp; 142 char *params = NULL, *cp;
143
146 /* No match */ 144 /* No match */
147 char bigbuf[MAX_BUF]; 145 char bigbuf[MAX_BUF];
148 int slen; 146 int slen;
149 147
150 /* Set up replyinfo before we modify any of the buffers - this is used 148 /* Set up replyinfo before we modify any of the buffers - this is used
151 * if we don't find a match. 149 * if we don't find a match.
152 */ 150 */
153 strcpy(bigbuf,"replyinfo "); 151 strcpy (bigbuf, "replyinfo ");
154 slen = strlen(bigbuf); 152 slen = strlen (bigbuf);
155 safe_strcat(bigbuf, buf, &slen, MAX_BUF); 153 safe_strcat (bigbuf, buf, &slen, MAX_BUF);
156 154
157 /* find the first space, make it null, and update the 155 /* find the first space, make it null, and update the
158 * params pointer. 156 * params pointer.
159 */ 157 */
160 for (cp = buf; *cp != '\0'; cp++) 158 for (cp = buf; *cp != '\0'; cp++)
161 if (*cp==' ') { 159 if (*cp == ' ')
160 {
162 *cp = '\0'; 161 *cp = '\0';
163 params = cp + 1; 162 params = cp + 1;
164 break; 163 break;
165 } 164 }
166 if (!strcmp(buf, "image_info")) send_image_info(ns, params); 165 if (!strcmp (buf, "image_info"))
167 else if (!strcmp(buf,"image_sums")) send_image_sums(ns, params); 166 send_image_info (ns, params);
168 else if (!strcmp(buf,"skill_info")) send_skill_info(ns, params); 167 else if (!strcmp (buf, "image_sums"))
169 else if (!strcmp(buf,"spell_paths")) send_spell_paths(ns, params); 168 send_image_sums (ns, params);
169 else if (!strcmp (buf, "skill_info"))
170 send_skill_info (ns, params);
171 else if (!strcmp (buf, "spell_paths"))
172 send_spell_paths (ns, params);
173 else
170 else Write_String_To_Socket(ns, bigbuf, len); 174 Write_String_To_Socket (ns, bigbuf, len);
171} 175}
172 176
173/** 177/**
174 * Handle client input. 178 * Handle client input.
175 * 179 *
178 * sock is the output socket information. pl is the player associated 182 * sock is the output socket information. pl is the player associated
179 * with this socket, null if no player (one of the init_sockets for just 183 * with this socket, null if no player (one of the init_sockets for just
180 * starting a connection) 184 * starting a connection)
181 */ 185 */
182 186
187void
183void HandleClient(NewSocket *ns, player *pl) 188HandleClient (NewSocket * ns, player *pl)
184{ 189{
185 int len=0,i,cnt; 190 int len = 0, i, cnt;
186 char *data; 191 char *data;
187 192
188 /* Loop through this - maybe we have several complete packets here. */ 193 /* Loop through this - maybe we have several complete packets here. */
189 // limit to a few commands only, though, as to not monopolise the server 194 // limit to a few commands only, though, as to not monopolise the server
190 for (cnt = 16; cnt--; ) { 195 for (cnt = 16; cnt--;)
196 {
191 /* If it is a player, and they don't have any speed left, we 197 /* If it is a player, and they don't have any speed left, we
192 * return, and will read in the data when they do have time. 198 * return, and will read in the data when they do have time.
193 */ 199 */
194 if (pl && pl->state==ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0) { 200 if (pl && pl->state == ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0)
201 {
195 return; 202 return;
196 }
197 203 }
204
198 i=SockList_ReadPacket(ns->fd, &ns->inbuf, MAXSOCKBUF-1); 205 i = SockList_ReadPacket (ns->fd, &ns->inbuf, MAXSOCKBUF - 1);
199 206
200 if (i<0) { 207 if (i < 0)
208 {
201#ifdef ESRV_DEBUG 209#ifdef ESRV_DEBUG
202 LOG(llevDebug,"HandleClient: Read error on connection player %s\n", (pl?pl->ob->name:"None")); 210 LOG (llevDebug, "HandleClient: Read error on connection player %s\n", (pl ? pl->ob->name : "None"));
203#endif 211#endif
204 /* Caller will take care of cleaning this up */ 212 /* Caller will take care of cleaning this up */
205 ns->status =Ns_Dead; 213 ns->status = Ns_Dead;
206 return; 214 return;
207 } 215 }
208 /* Still dont have a full packet */ 216 /* Still dont have a full packet */
217 if (i == 0)
209 if (i==0) return; 218 return;
210 219
211// //D//TODO//temporarily log long commands 220// //D//TODO//temporarily log long commands
212// if (ns->inbuf.len >= 40 && pl && pl->ob) 221// if (ns->inbuf.len >= 40 && pl && pl->ob)
213// LOG (llevDebug, "HandleClient: long comamnd from <%s,%s> %d<%s>\n", pl->ob->name, ns->host, ns->inbuf.len, ns->inbuf.buf + 2); 222// LOG (llevDebug, "HandleClient: long comamnd from <%s,%s> %d<%s>\n", pl->ob->name, ns->host, ns->inbuf.len, ns->inbuf.buf + 2);
214 223
215 /* First, break out beginning word. There are at least 224 /* First, break out beginning word. There are at least
216 * a few commands that do not have any paremeters. If 225 * a few commands that do not have any paremeters. If
217 * we get such a command, don't worry about trying 226 * we get such a command, don't worry about trying
218 * to break it up. 227 * to break it up.
219 */ 228 */
220 data = (char *)strchr((char*)ns->inbuf.buf +2, ' '); 229 data = (char *) strchr ((char *) ns->inbuf.buf + 2, ' ');
221 if (data) { 230 if (data)
231 {
222 *data='\0'; 232 *data = '\0';
223 data++; 233 data++;
224 len = ns->inbuf.len - (data - (char*)ns->inbuf.buf); 234 len = ns->inbuf.len - (data - (char *) ns->inbuf.buf);
225 } 235 }
236 else
226 else len=0; 237 len = 0;
227 238
228 ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ 239 ns->inbuf.buf[ns->inbuf.len] = '\0'; /* Terminate buffer - useful for string data */
229 for (i=0; nscommands[i].cmdname !=NULL; i++) { 240 for (i = 0; nscommands[i].cmdname != NULL; i++)
241 {
230 if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) { 242 if (strcmp ((char *) ns->inbuf.buf + 2, nscommands[i].cmdname) == 0)
243 {
231 nscommands[i].cmdproc((char*)data,len,ns); 244 nscommands[i].cmdproc ((char *) data, len, ns);
232 ns->inbuf.len=0; 245 ns->inbuf.len = 0;
233 return;//D// not doing this causes random memory corruption 246 return; //D// not doing this causes random memory corruption
234 goto next_packet; 247 goto next_packet;
235 }
236 } 248 }
249 }
237 /* Player must be in the playing state or the flag on the 250 /* Player must be in the playing state or the flag on the
238 * the command must be zero for the user to use the command - 251 * the command must be zero for the user to use the command -
239 * otherwise, a player cam save, be in the play_again state, and 252 * otherwise, a player cam save, be in the play_again state, and
240 * the map they were on gets swapped out, yet things that try to look 253 * the map they were on gets swapped out, yet things that try to look
241 * at the map causes a crash. If the command is valid, but 254 * at the map causes a crash. If the command is valid, but
242 * one they can't use, we still swallow it up. 255 * one they can't use, we still swallow it up.
243 */ 256 */
257 if (pl)
244 if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) { 258 for (i = 0; plcommands[i].cmdname != NULL; i++)
259 {
245 if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) { 260 if (strcmp ((char *) ns->inbuf.buf + 2, plcommands[i].cmdname) == 0)
261 {
246 if (pl->state == ST_PLAYING || !(plcommands[i].flag & 1)) 262 if (pl->state == ST_PLAYING || !(plcommands[i].flag & 1))
247 plcommands[i].cmdproc((char*)data,len,pl); 263 plcommands[i].cmdproc ((char *) data, len, pl);
248 ns->inbuf.len=0; 264 ns->inbuf.len = 0;
249 //D// not doing this causes random memory corruption 265 //D// not doing this causes random memory corruption
250 if (plcommands[i].flag & 2) 266 if (plcommands[i].flag & 2)
251 goto next_packet; 267 goto next_packet;
252 return; 268 return;
253 } 269 }
254 } 270 }
255 /* If we get here, we didn't find a valid command. Logging 271 /* If we get here, we didn't find a valid command. Logging
256 * this might be questionable, because a broken client/malicious 272 * this might be questionable, because a broken client/malicious
257 * user could certainly send a whole bunch of invalid commands. 273 * user could certainly send a whole bunch of invalid commands.
258 */ 274 */
259 LOG(llevDebug,"Bad command from client (%s)\n",ns->inbuf.buf+2); 275 LOG (llevDebug, "Bad command from client (%s)\n", ns->inbuf.buf + 2);
260 next_packet: 276 next_packet:
261 ; 277 ;
262 } 278 }
263} 279}
264 280
265 281
266/***************************************************************************** 282/*****************************************************************************
269 * sending. 285 * sending.
270 * 286 *
271 ******************************************************************************/ 287 ******************************************************************************/
272 288
273#ifdef WATCHDOG 289#ifdef WATCHDOG
290
274/** 291/**
275 * Tell watchdog that we are still alive 292 * Tell watchdog that we are still alive
276 * 293 *
277 * I put the function here since we should hopefully already be getting 294 * I put the function here since we should hopefully already be getting
278 * all the needed include files for socket support 295 * all the needed include files for socket support
279 */ 296 */
280 297
298void
281void watchdog(void) 299watchdog (void)
282{ 300{
283 static int fd=-1; 301 static int fd = -1;
284 static struct sockaddr_in insock; 302 static struct sockaddr_in insock;
285 303
286 if (fd==-1) 304 if (fd == -1)
287 { 305 {
288 struct protoent *protoent; 306 struct protoent *protoent;
289 307
290 if ((protoent=getprotobyname("udp"))==NULL || 308 if ((protoent = getprotobyname ("udp")) == NULL || (fd = socket (PF_INET, SOCK_DGRAM, protoent->p_proto)) == -1)
291 (fd=socket(PF_INET, SOCK_DGRAM, protoent->p_proto))==-1)
292 { 309 {
293 return; 310 return;
294 } 311 }
295 insock.sin_family=AF_INET; 312 insock.sin_family = AF_INET;
296 insock.sin_port=htons((unsigned short)13325); 313 insock.sin_port = htons ((unsigned short) 13325);
297 insock.sin_addr.s_addr=inet_addr("127.0.0.1"); 314 insock.sin_addr.s_addr = inet_addr ("127.0.0.1");
298 } 315 }
299 sendto(fd,(void *)&fd,1,0,(struct sockaddr *)&insock,sizeof(insock)); 316 sendto (fd, (void *) &fd, 1, 0, (struct sockaddr *) &insock, sizeof (insock));
300} 317}
301#endif 318#endif
302 319
320void
303void flush_sockets(void) 321flush_sockets (void)
304{ 322{
305 player *pl; 323 player *pl;
306 324
307 for (pl = first_player; pl != NULL; pl = pl->next) 325 for (pl = first_player; pl != NULL; pl = pl->next)
308 if (pl->socket.status != Ns_Dead) 326 if (pl->socket.status != Ns_Dead)
314 * 332 *
315 * A bit of this code is grabbed out of socket.c 333 * A bit of this code is grabbed out of socket.c
316 * There are 2 lists we need to look through - init_sockets is a list 334 * There are 2 lists we need to look through - init_sockets is a list
317 * 335 *
318 */ 336 */
337void
319void doeric_server(void) 338doeric_server (void)
320{ 339{
321 int i, pollret; 340 int i, pollret;
322 fd_set tmp_read, tmp_exceptions, tmp_write; 341 fd_set tmp_read, tmp_exceptions, tmp_write;
323 struct sockaddr_in addr; 342 struct sockaddr_in addr;
324 socklen_t addrlen=sizeof(struct sockaddr); 343 socklen_t addrlen = sizeof (struct sockaddr);
325 player *pl, *next; 344 player *pl, *next;
326 345
327#ifdef CS_LOGSTATS 346#ifdef CS_LOGSTATS
328 if ((time(NULL)-cst_lst.time_start)>=CS_LOGTIME) 347 if ((time (NULL) - cst_lst.time_start) >= CS_LOGTIME)
329 write_cs_stats(); 348 write_cs_stats ();
330#endif 349#endif
331 350
332 FD_ZERO(&tmp_read); 351 FD_ZERO (&tmp_read);
333 FD_ZERO(&tmp_write); 352 FD_ZERO (&tmp_write);
334 FD_ZERO(&tmp_exceptions); 353 FD_ZERO (&tmp_exceptions);
335 354
336 for(i=0;i<socket_info.allocated_sockets;i++) { 355 for (i = 0; i < socket_info.allocated_sockets; i++)
356 {
337 if (init_sockets[i].status == Ns_Dead) { 357 if (init_sockets[i].status == Ns_Dead)
358 {
338 free_newsocket(&init_sockets[i]); 359 free_newsocket (&init_sockets[i]);
339 init_sockets[i].status = Ns_Avail; 360 init_sockets[i].status = Ns_Avail;
340 socket_info.nconns--; 361 socket_info.nconns--;
362 }
341 } else if (init_sockets[i].status != Ns_Avail){ 363 else if (init_sockets[i].status != Ns_Avail)
364 {
342 FD_SET((uint32)init_sockets[i].fd, &tmp_read); 365 FD_SET ((uint32) init_sockets[i].fd, &tmp_read);
343 FD_SET((uint32)init_sockets[i].fd, &tmp_write); 366 FD_SET ((uint32) init_sockets[i].fd, &tmp_write);
344 FD_SET((uint32)init_sockets[i].fd, &tmp_exceptions); 367 FD_SET ((uint32) init_sockets[i].fd, &tmp_exceptions);
345 } 368 }
346 } 369 }
347 370
348 /* Go through the players. Let the loop set the next pl value, 371 /* Go through the players. Let the loop set the next pl value,
349 * since we may remove some 372 * since we may remove some
350 */ 373 */
351 for (pl=first_player; pl!=NULL; ) { 374 for (pl = first_player; pl != NULL;)
375 {
352 if (pl->socket.status == Ns_Dead) { 376 if (pl->socket.status == Ns_Dead)
377 {
353 player *npl=pl->next; 378 player *npl = pl->next;
354 379
355 save_player(pl->ob, 0); 380 save_player (pl->ob, 0);
356 if(!QUERY_FLAG(pl->ob,FLAG_REMOVED)) { 381 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
382 {
357 terminate_all_pets(pl->ob); 383 terminate_all_pets (pl->ob);
358 remove_ob(pl->ob); 384 remove_ob (pl->ob);
359 } 385 }
360 leave(pl,1); 386 leave (pl, 1);
361 final_free_player(pl); 387 final_free_player (pl);
362 pl=npl; 388 pl = npl;
389 }
390 else
363 } 391 {
364 else {
365 FD_SET((uint32)pl->socket.fd, &tmp_read); 392 FD_SET ((uint32) pl->socket.fd, &tmp_read);
366 FD_SET((uint32)pl->socket.fd, &tmp_write); 393 FD_SET ((uint32) pl->socket.fd, &tmp_write);
367 FD_SET((uint32)pl->socket.fd, &tmp_exceptions); 394 FD_SET ((uint32) pl->socket.fd, &tmp_exceptions);
368 pl=pl->next; 395 pl = pl->next;
369 } 396 }
370 } 397 }
371 398
372 /* Reset timeout each time, since some OS's will change the values on 399 /* Reset timeout each time, since some OS's will change the values on
373 * the return from select. 400 * the return from select.
374 */ 401 */
375 socket_info.timeout.tv_sec = 0; 402 socket_info.timeout.tv_sec = 0;
376 socket_info.timeout.tv_usec = 0; 403 socket_info.timeout.tv_usec = 0;
377 404
378 pollret= select(socket_info.max_filedescriptor, &tmp_read, &tmp_write, 405 pollret = select (socket_info.max_filedescriptor, &tmp_read, &tmp_write, &tmp_exceptions, &socket_info.timeout);
379 &tmp_exceptions, &socket_info.timeout);
380 406
381 if (pollret==-1) { 407 if (pollret == -1)
408 {
382 LOG(llevError, "select failed: %s\n", strerror(errno)); 409 LOG (llevError, "select failed: %s\n", strerror (errno));
383 return; 410 return;
384 } 411 }
385 412
386 /* We need to do some of the processing below regardless */ 413 /* We need to do some of the processing below regardless */
414
387/* if (!pollret) return;*/ 415/* if (!pollret) return;*/
388 416
389 /* Following adds a new connection */ 417 /* Following adds a new connection */
390 if (pollret && FD_ISSET(init_sockets[0].fd, &tmp_read)) { 418 if (pollret && FD_ISSET (init_sockets[0].fd, &tmp_read))
419 {
391 int newsocknum=0; 420 int newsocknum = 0;
392 421
393#ifdef ESRV_DEBUG 422#ifdef ESRV_DEBUG
394 LOG(llevDebug,"doeric_server: New Connection\n"); 423 LOG (llevDebug, "doeric_server: New Connection\n");
395#endif 424#endif
396 /* If this is the case, all sockets currently in used */ 425 /* If this is the case, all sockets currently in used */
397 if (socket_info.allocated_sockets <= socket_info.nconns) { 426 if (socket_info.allocated_sockets <= socket_info.nconns)
427 {
398 init_sockets = (NewSocket *) realloc(init_sockets,sizeof(NewSocket)*(socket_info.nconns+1)); 428 init_sockets = (NewSocket *) realloc (init_sockets, sizeof (NewSocket) * (socket_info.nconns + 1));
429 if (!init_sockets)
399 if (!init_sockets) fatal(OUT_OF_MEMORY); 430 fatal (OUT_OF_MEMORY);
400 newsocknum = socket_info.allocated_sockets; 431 newsocknum = socket_info.allocated_sockets;
401 socket_info.allocated_sockets++; 432 socket_info.allocated_sockets++;
402 init_sockets[newsocknum].faces_sent_len = nrofpixmaps; 433 init_sockets[newsocknum].faces_sent_len = nrofpixmaps;
403 init_sockets[newsocknum].faces_sent = (uint8*) malloc(nrofpixmaps*sizeof(*init_sockets[newsocknum].faces_sent)); 434 init_sockets[newsocknum].faces_sent = (uint8 *) malloc (nrofpixmaps * sizeof (*init_sockets[newsocknum].faces_sent));
404 if (!init_sockets[newsocknum].faces_sent) fatal(OUT_OF_MEMORY); 435 if (!init_sockets[newsocknum].faces_sent)
436 fatal (OUT_OF_MEMORY);
405 init_sockets[newsocknum].status = Ns_Avail; 437 init_sockets[newsocknum].status = Ns_Avail;
438 }
439 else
406 } 440 {
407 else {
408 int j; 441 int j;
409 442
410 for (j=1; j<socket_info.allocated_sockets; j++) 443 for (j = 1; j < socket_info.allocated_sockets; j++)
411 if (init_sockets[j].status == Ns_Avail) { 444 if (init_sockets[j].status == Ns_Avail)
445 {
412 newsocknum=j; 446 newsocknum = j;
413 break; 447 break;
414 } 448 }
415 } 449 }
416 init_sockets[newsocknum].fd=accept(init_sockets[0].fd, (struct sockaddr *)&addr, &addrlen); 450 init_sockets[newsocknum].fd = accept (init_sockets[0].fd, (struct sockaddr *) &addr, &addrlen);
417 if (init_sockets[newsocknum].fd==-1) { 451 if (init_sockets[newsocknum].fd == -1)
452 {
418 LOG(llevError, "accept failed: %s\n", strerror(errno)); 453 LOG (llevError, "accept failed: %s\n", strerror (errno));
454 }
455 else
419 } 456 {
420 else {
421 char buf[MAX_BUF]; 457 char buf[MAX_BUF];
422 long ip; 458 long ip;
423 NewSocket *ns; 459 NewSocket *ns;
424 460
425 ns = &init_sockets[newsocknum]; 461 ns = &init_sockets[newsocknum];
426 462
427 ip = ntohl(addr.sin_addr.s_addr); 463 ip = ntohl (addr.sin_addr.s_addr);
428 sprintf(buf, "%ld.%ld.%ld.%ld", (ip>>24)&255, (ip>>16)&255, (ip>>8)&255, ip&255); 464 sprintf (buf, "%ld.%ld.%ld.%ld", (ip >> 24) & 255, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
429 465
430 if (checkbanned(NULL, buf)) { 466 if (checkbanned (NULL, buf))
467 {
431 LOG(llevInfo, "Banned host tried to connect: [%s]\n", buf); 468 LOG (llevInfo, "Banned host tried to connect: [%s]\n", buf);
432 close(init_sockets[newsocknum].fd); 469 close (init_sockets[newsocknum].fd);
433 init_sockets[newsocknum].fd = -1; 470 init_sockets[newsocknum].fd = -1;
471 }
472 else
434 } 473 {
435 else {
436 InitConnection(ns, buf); 474 InitConnection (ns, buf);
437 socket_info.nconns++; 475 socket_info.nconns++;
438 }
439 } 476 }
477 }
440 } 478 }
441 479
442 /* Check for any exceptions/input on the sockets */ 480 /* Check for any exceptions/input on the sockets */
481 if (pollret)
443 if (pollret) for(i=1;i<socket_info.allocated_sockets;i++) { 482 for (i = 1; i < socket_info.allocated_sockets; i++)
483 {
444 if (init_sockets[i].status == Ns_Avail) continue; 484 if (init_sockets[i].status == Ns_Avail)
485 continue;
445 if (FD_ISSET(init_sockets[i].fd,&tmp_exceptions)) { 486 if (FD_ISSET (init_sockets[i].fd, &tmp_exceptions))
487 {
446 free_newsocket(&init_sockets[i]); 488 free_newsocket (&init_sockets[i]);
447 init_sockets[i].status = Ns_Avail; 489 init_sockets[i].status = Ns_Avail;
448 socket_info.nconns--; 490 socket_info.nconns--;
449 continue; 491 continue;
450 } 492 }
451 if (FD_ISSET(init_sockets[i].fd, &tmp_read)) { 493 if (FD_ISSET (init_sockets[i].fd, &tmp_read))
494 {
452 HandleClient(&init_sockets[i], NULL); 495 HandleClient (&init_sockets[i], NULL);
453 } 496 }
454 if (FD_ISSET(init_sockets[i].fd, &tmp_write)) { 497 if (FD_ISSET (init_sockets[i].fd, &tmp_write))
498 {
455 init_sockets[i].can_write=1; 499 init_sockets[i].can_write = 1;
456 } 500 }
457 } 501 }
458 502
459 /* This does roughly the same thing, but for the players now */ 503 /* This does roughly the same thing, but for the players now */
460 for (pl=first_player; pl!=NULL; pl=next) { 504 for (pl = first_player; pl != NULL; pl = next)
505 {
461 506
462 next=pl->next; 507 next = pl->next;
463 if (pl->socket.status==Ns_Dead) continue; 508 if (pl->socket.status == Ns_Dead)
509 continue;
464 510
465 if (FD_ISSET(pl->socket.fd,&tmp_write)) { 511 if (FD_ISSET (pl->socket.fd, &tmp_write))
512 {
466 if (!pl->socket.can_write) { 513 if (!pl->socket.can_write)
514 {
467#if 0 515#if 0
468 LOG(llevDebug,"Player %s socket now write enabled\n", pl->ob->name); 516 LOG (llevDebug, "Player %s socket now write enabled\n", pl->ob->name);
469#endif 517#endif
470 pl->socket.can_write=1; 518 pl->socket.can_write = 1;
471 write_socket_buffer(&pl->socket); 519 write_socket_buffer (&pl->socket);
472 } 520 }
473 /* if we get an error on the write_socket buffer, no reason to 521 /* if we get an error on the write_socket buffer, no reason to
474 * continue on this socket. 522 * continue on this socket.
475 */ 523 */
476 if (pl->socket.status==Ns_Dead) continue; 524 if (pl->socket.status == Ns_Dead)
525 continue;
477 } 526 }
527 else
478 else pl->socket.can_write=0; 528 pl->socket.can_write = 0;
479 529
480 if (FD_ISSET(pl->socket.fd,&tmp_exceptions)) { 530 if (FD_ISSET (pl->socket.fd, &tmp_exceptions))
531 {
481 save_player(pl->ob, 0); 532 save_player (pl->ob, 0);
482 if(!QUERY_FLAG(pl->ob,FLAG_REMOVED)) { 533 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
534 {
483 terminate_all_pets(pl->ob); 535 terminate_all_pets (pl->ob);
484 remove_ob(pl->ob); 536 remove_ob (pl->ob);
485 } 537 }
486 leave(pl,1); 538 leave (pl, 1);
487 final_free_player(pl); 539 final_free_player (pl);
540 }
541 else
488 } 542 {
489 else {
490 HandleClient(&pl->socket, pl); 543 HandleClient (&pl->socket, pl);
491 /* If the player has left the game, then the socket status 544 /* If the player has left the game, then the socket status
492 * will be set to this be the leave function. We don't 545 * will be set to this be the leave function. We don't
493 * need to call leave again, as it has already been called 546 * need to call leave again, as it has already been called
494 * once. 547 * once.
495 */ 548 */
496 if (pl->socket.status==Ns_Dead) { 549 if (pl->socket.status == Ns_Dead)
550 {
497 save_player(pl->ob, 0); 551 save_player (pl->ob, 0);
498 if(!QUERY_FLAG(pl->ob,FLAG_REMOVED)) { 552 if (!QUERY_FLAG (pl->ob, FLAG_REMOVED))
553 {
499 terminate_all_pets(pl->ob); 554 terminate_all_pets (pl->ob);
500 remove_ob(pl->ob); 555 remove_ob (pl->ob);
501 } 556 }
502 leave(pl,1); 557 leave (pl, 1);
503 final_free_player(pl); 558 final_free_player (pl);
559 }
504 } else { 560 else
561 {
505 562
506 /* Update the players stats once per tick. More efficient than 563 /* Update the players stats once per tick. More efficient than
507 * sending them whenever they change, and probably just as useful 564 * sending them whenever they change, and probably just as useful
508 */ 565 */
509 esrv_update_stats(pl); 566 esrv_update_stats (pl);
510 if (pl->last_weight != -1 && pl->last_weight != WEIGHT(pl->ob)) { 567 if (pl->last_weight != -1 && pl->last_weight != WEIGHT (pl->ob))
568 {
511 esrv_update_item(UPD_WEIGHT, pl->ob, pl->ob); 569 esrv_update_item (UPD_WEIGHT, pl->ob, pl->ob);
512 if(pl->last_weight != WEIGHT(pl->ob)) 570 if (pl->last_weight != WEIGHT (pl->ob))
513 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)); 571 LOG (llevError, "esrv_update_item(UPD_WEIGHT) did not set player weight: is %lu, should be %lu\n",
572 (unsigned long) pl->last_weight, WEIGHT (pl->ob));
514 } 573 }
515 /* draw_client_map does sanity checking that map is 574 /* draw_client_map does sanity checking that map is
516 * valid, so don't do it here. 575 * valid, so don't do it here.
517 */ 576 */
518 draw_client_map(pl->ob); 577 draw_client_map (pl->ob);
519 if (pl->socket.update_look) esrv_draw_look(pl->ob); 578 if (pl->socket.update_look)
579 esrv_draw_look (pl->ob);
520 } 580 }
521 } 581 }
522 } 582 }
523} 583}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines