ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/loop.C
Revision: 1.37
Committed: Mon Jan 8 18:18:36 2007 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.36: +5 -3 lines
Log Message:
- move most last_* values into socket, where they belong
- this actually saved a lot of space in the text segment,
  which might mean less complicated pointer accesses, because
  the data is no where it belongs, mostly.

File Contents

# User Rev Content
1 elmex 1.1 /*
2     CrossFire, A Multiplayer game for X-windows
3    
4 pippijn 1.36 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 elmex 1.1 Copyright (C) 2002-2003 Mark Wedel & The Crossfire Development Team
6     Copyright (C) 1992 Frank Tore Johansen
7    
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU General Public License for more details.
17    
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21    
22 root 1.7 The author can be reached via e-mail to <crossfire@schmorp.de>
23 elmex 1.1 */
24    
25     /**
26     * \file
27     * Main client/server loops.
28     *
29     * \date 2003-12-02
30     *
31     * loop.c mainly deals with initialization and higher level socket
32 root 1.26 * maintanance (checking for lost connections and if data has arrived.)
33 elmex 1.1 */
34    
35    
36     #include <global.h>
37 root 1.10 #include <sproto.h>
38     #include <sockproto.h>
39 elmex 1.1
40 pippijn 1.8 #include <sys/types.h>
41     #include <sys/time.h>
42     #include <sys/socket.h>
43     #include <netinet/in.h>
44     #include <netdb.h>
45 elmex 1.1
46 root 1.16 #include <unistd.h>
47     #include <arpa/inet.h>
48 elmex 1.1
49     #include <loader.h>
50    
51 root 1.20 #define MAX_QUEUE_DEPTH 500 //TODO
52 root 1.34 #define MAX_QUEUE_BACKLOG 3. //TODO
53 elmex 1.1
54 root 1.21 void
55     client::reset_state ()
56     {
57     if (!pl)
58     return;
59    
60     pl->run_on = 0;
61     pl->fire_on = 0;
62     }
63 elmex 1.1
64 root 1.20 void
65     client::queue_command (packet_type *handler, char *data, int datalen)
66 root 1.6 {
67 root 1.20 tstamp stamp = now ();
68 elmex 1.1
69 root 1.20 if (cmd_queue.size () >= MAX_QUEUE_DEPTH)
70 root 1.21 {
71     //TODO: just disconnect here?
72     reset_state ();
73     send_packet_printf ("drawinfo %d command queue overflow, ignoring.", NDI_RED);
74     }
75 root 1.20 else
76 root 1.24 {
77     cmd_queue.push_back (command ());
78     command &cmd = cmd_queue.back ();
79     cmd.stamp = stamp;
80     cmd.handler = handler;
81 root 1.25 cmd.data = salloc<char> (datalen + 1, data);
82 root 1.24 cmd.datalen = datalen;
83     }
84 root 1.20 }
85 elmex 1.1
86 root 1.20 bool
87     client::handle_command ()
88 elmex 1.1 {
89 root 1.26 bool skipping = false;
90 elmex 1.1
91 root 1.26 while (!cmd_queue.empty ()
92 root 1.31 && !(state == ST_PLAYING && pl->ob && pl->ob->speed_left < 0))
93 root 1.26 {
94     command &cmd = cmd_queue.front ();
95 root 1.6
96 root 1.26 if (cmd.stamp + MAX_QUEUE_BACKLOG < now ())
97     {
98     if (!skipping)
99     {
100     skipping = true;
101     reset_state ();
102     send_packet_printf ("drawinfo %d ignoring delayed commands.", NDI_RED);
103     }
104 root 1.11
105 root 1.26 cmd_queue.pop_front ();
106     }
107     else
108     {
109     execute (cmd.handler, cmd.data, cmd.datalen);
110     cmd_queue.pop_front ();
111     return true;
112     }
113 root 1.21 }
114 root 1.6
115 root 1.26 return false;
116 elmex 1.1 }
117    
118 root 1.6 void
119     flush_sockets (void)
120 elmex 1.1 {
121 root 1.19 for (sockvec::iterator i = clients.begin (); i != clients.end (); ++i)
122 root 1.31 (*i)->flush ();
123 elmex 1.1 }
124    
125     /**
126 root 1.10 * This checks the sockets for input, does the right thing.
127 elmex 1.1 *
128     * A bit of this code is grabbed out of socket.c
129     * There are 2 lists we need to look through - init_sockets is a list
130     *
131     */
132 root 1.6 void
133     doeric_server (void)
134 elmex 1.1 {
135     #ifdef CS_LOGSTATS
136 root 1.6 if ((time (NULL) - cst_lst.time_start) >= CS_LOGTIME)
137     write_cs_stats ();
138 elmex 1.1 #endif
139    
140 root 1.33 //TODO: should not be done here, either
141 root 1.35 for (int i = 0; i < clients.size (); ++i)
142 root 1.6 {
143 root 1.35 client *s = clients [i];
144     player *pl = s->pl;
145 elmex 1.1
146 root 1.35 if (pl && pl->ns && !pl->ns->destroyed ())
147 root 1.6 {
148 root 1.37 client *ns = pl->ns;
149    
150 root 1.10 /* Update the players stats once per tick. More efficient than
151     * sending them whenever they change, and probably just as useful
152 root 1.6 */
153 root 1.10 esrv_update_stats (pl);
154 root 1.20
155 root 1.37 if (ns->last_weight != -1 && ns->last_weight != WEIGHT (pl->ob))
156 root 1.6 {
157 root 1.10 esrv_update_item (UPD_WEIGHT, pl->ob, pl->ob);
158 root 1.37 if (ns->last_weight != WEIGHT (pl->ob))
159 root 1.10 LOG (llevError, "esrv_update_item(UPD_WEIGHT) did not set player weight: is %lu, should be %lu\n",
160 root 1.37 (unsigned long) ns->last_weight, WEIGHT (pl->ob));
161 root 1.6 }
162    
163 root 1.10 draw_client_map (pl->ob);
164 root 1.20
165 root 1.14 if (s->update_look)
166 root 1.10 esrv_draw_look (pl->ob);
167 root 1.3 }
168 root 1.33
169     s->refcnt_chk ();
170 elmex 1.1 }
171     }
172 root 1.10