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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines