ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/client.h
(Generate patch)

Comparing deliantra/server/include/client.h (file contents):
Revision 1.3 by root, Fri Dec 15 20:08:45 2006 UTC vs.
Revision 1.111 by root, Sun Nov 11 04:29:11 2012 UTC

1
2/* 1/*
3 CrossFire, A Multiplayer game for the X Window System 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
4 3 *
5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
6 Copyright (C) 1992 Frank Tore Johansen 5 *
7 6 * Deliantra is free software: you can redistribute it and/or modify it under
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 7 * the terms of the Affero GNU General Public License as published by the
10 the Free Software Foundation; either version 2 of the License, or 8 * Free Software Foundation, either version 3 of the License, or (at your
11 (at your option) any later version. 9 * option) any later version.
12 10 *
13 This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 14 * GNU General Public License for more details.
17 15 *
18 You should have received a copy of the GNU General Public License 16 * You should have received a copy of the Affero GNU General Public License
19 along with this program; if not, write to the Free Software 17 * and the GNU General Public License along with this program. If not, see
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * <http://www.gnu.org/licenses/>.
21 19 *
22 The author can be reached via e-mail to crossfire@schmorp.de 20 * The authors can be reached via e-mail to <support@deliantra.net>
23*/ 21 */
24
25/*
26 newserver.h defines various structures and values that are use for the
27 new client server communication method. Values defined here are only
28 used on the server side code. For shared client/server values, see
29 newclient.h
30*/
31 22
32#ifndef CLIENT_H 23#ifndef CLIENT_H
33#define CLIENT_H 24#define CLIENT_H
34 25
35/* Reduce this from 50 to 5 - as it is now, there will never be more 26#if HAVE_TCP_INFO
36 * than 3 anyways. 27# include <netinet/tcp.h>
37 */ 28#else
29 struct tcp_info {
30 // dummy
31 int tcpi_state;
32 int tcpi_ca_state;
33 int tcpi_retransmits;
34 int tcpi_probes;
35 int tcpi_backoff;
36 int tcpi_options;
37 int tcpi_snd_wscale;
38 int tcpi_rcv_wscale;
39 int tcpi_rto;
40 int tcpi_ato;
41 int tcpi_snd_mss;
42 int tcpi_rcv_mss;
43 int tcpi_unacked;
44 int tcpi_sacked;
45 int tcpi_lost;
46 int tcpi_retrans;
47 int tcpi_fackets;
48 int tcpi_last_data_sent;
49 int tcpi_last_ack_sent;
50 int tcpi_last_data_recv;
51 int tcpi_last_ack_recv;
52 int tcpi_pmtu;
53 int tcpi_rcv_ssthresh;
54 int tcpi_rtt;
55 int tcpi_rttvar;
56 int tcpi_snd_ssthresh;
57 int tcpi_snd_cwnd;
58 int tcpi_advmss;
59 int tcpi_reordering;
60 };
61#endif
38 62
39#define NUM_LOOK_OBJECTS 50 63//+GPL
64
65// (possibly) max. number of objects "per page" in the ground container
66#define FLOORBOX_PAGESIZE 50
40 67
41struct MapCell 68struct MapCell
42{ 69{
43 UUID player; // this is, unfortunately, very wasteful of memory space, but pretty bandwidth-efficient 70 tag_t player; // this is, unfortunately, very wasteful of memory space, but pretty bandwidth-efficient
44 int count; /* This is really darkness in the map1 command */ 71 int count; /* This is really darkness in the map1 command */
45 uint16 faces[MAP_LAYERS]; 72 faceidx faces[MAP_LAYERS];
46 uint16 smooth[MAP_LAYERS];
47 unsigned char stat_hp; // health of something in this space, or 0 73 unsigned char stat_hp; // health of something in this space, or 0
48 unsigned char flags; 74 unsigned char flags;
75 uint8_t smooth[MAP_LAYERS];
49}; 76};
50 77
51/* This basically defines the largest size an
52 * archetype may be - it is used for allocation of
53 * some structures, as well as determining how far
54 * we should look for the heads of big images.
55 */
56#define MAX_HEAD_OFFSET 8
57
58#define MAX_CLIENT_X (MAP_CLIENT_X + MAX_HEAD_OFFSET) 78#define MAX_CLIENT_X MAP_CLIENT_X
59#define MAX_CLIENT_Y (MAP_CLIENT_Y + MAX_HEAD_OFFSET) 79#define MAX_CLIENT_Y MAP_CLIENT_Y
60 80
61struct Map 81struct Map
62{ 82{
63 struct MapCell cells[MAX_CLIENT_X][MAX_CLIENT_Y]; 83 struct MapCell cells[MAX_CLIENT_X][MAX_CLIENT_Y];
64}; 84};
65 85
66/* True max is 16383 given current map compaction method */ 86/* True max is 16383 given current map compaction method */
67# define MAXANIMNUM 2000 87#define MAXANIMNUM 10000
68 88
69struct statsinfo 89struct statsinfo
70{ 90{
71 char *range, *title; 91 char *range, *title;
72}; 92};
73 93
94// states the socket can be in
95enum {
96 ST_DEAD, // socket is dead
97 ST_SETUP, // initial handshake / setup / login
98 ST_PLAYING, // logged in an playing
99 ST_CUSTOM, // waiting for custom reply
100
101 ST_GET_PARTY_PASSWORD,
102};
103
104// a handler for a specific type of packet
105enum {
106 PF_PLAYER = 0x01, // must have valid player / will by synchronised
107 PF_PLAYING = 0x02, // must be in playing state
108 PF_COMMAND0 = 0x04, // command starts at offset 0
109 PF_COMMAND6 = 0x08, // command starts at offset 6
110};
111
112// face types. bit 0 means "has meta info prepended"
113enum {
114 FT_FACE = 0 * 2 + 0, // faces (images)
115 FT_MUSIC = 1 * 2 + 1, // background music
116 FT_SOUND = 2 * 2 + 1, // effects
117 FT_RSRC = 3 * 2 + 0, // generic data files
118 FT_NUM,
119};
120
121struct packet_type
122{
123 const char *name;
124 void *cb;
125 int flags;
126};
127
128struct command
129{
130 tstamp stamp;
131 const packet_type *handler;
132 char *data;
133 int datalen;
134};
135
136//-GPL
137
138/* how many times we are allowed to give the wrong password before being kicked. */
139#define MAX_PASSWORD_FAILURES 5
140
74/* This contains basic information on the socket structure. status is its 141/* This contains basic information on the socket connection. status is its
75 * current state. we set up our on buffers for sending/receiving, so we can 142 * current state. we set up our on buffers for sending/receiving, so we can
76 * handle some higher level functions. fd is the actual file descriptor we 143 * handle some higher level functions. fd is the actual file descriptor we
77 * are using. 144 * are using.
78 */ 145 */
79
80enum Sock_Status { Ns_Add, Ns_Dead };
81
82/* Only one map mode can actually be used, so lets make it a switch
83 * instead of having a bunch of different fields that needed to
84 * get toggled.
85 */
86enum MapMode { Map0Cmd = 0, Map1Cmd = 1, Map1aCmd = 2 };
87
88/* The following is the setup for a ring buffer for storing outbut
89 * data that the OS can't handle right away.
90 */
91
92struct Buffer
93{
94 char data[SOCKETBUFSIZE];
95 int start;
96 int len;
97};
98
99/* how many times we are allowed to give the wrong password before being kicked. */
100#define MAX_PASSWORD_FAILURES 5
101
102ACC_CLASS (client) // should become player when newsocket is a baseclass of player 146INTERFACE_CLASS (client) // should become player when newsocket is a baseclass of player
103struct client : zero_initialised, attachable_base 147struct client : zero_initialised, attachable
104{ 148{
105 enum Sock_Status status;
106 int ACC (RW, fd); 149 int ACC (RW, fd);
107 unsigned int inbuf_len; // number of bytes valid in inbuf 150 unsigned int inbuf_len; // number of bytes valid in inbuf
151 statsinfo stats;
152 object_vector_index ACC (RO, active);
153 player_ptr ACC (RO, pl);
154
155 char *ACC (RW, host); /* Which host it is connected from (ip address) */
156 uint8 ACC (RW, state); /* Input state of the player (name, password, etc */
157
158 sint8 ACC (RW, last_level); /* Last level we sent to client */
159 uint16 ACC (RW, last_flags); /* fire/run on flags for last tick */
160 float ACC (RW, last_weapon_sp); /* if diff than weapon_sp, update client */
161 sint32 ACC (RW, last_weight); /* Last weight as sent to client; -1 means do not send weight */
162 sint32 ACC (RW, last_weight_limit); /* Last weight limit transmitted to client */
163 uint32 ACC (RW, last_path_attuned); /* Last spell attunment sent to client */
164 uint32 ACC (RW, last_path_repelled); /* Last spell repelled sent to client */
165 uint32 ACC (RW, last_path_denied); /* Last spell denied sent to client */
166 living ACC (RO, last_stats); /* Last stats as sent to client */
167 float ACC (RW, last_speed); /* Last speed as sent to client */
168 sint16 ACC (RW, last_resist[NROFATTACKS]);/* last resist values sent to client */
169 sint64 ACC (RW, last_skill_exp[CS_NUM_SKILLS]);/* shadow register. if != exp. obj update client */
170
171 bool ACC (RW, afk); /* player is afk */
172 bool ACC (RW, sent_scroll);
173 bool ACC (RW, sound); /* does the client want sound */
174 bool ACC (RW, bumpmsg); /* give message when bumping into walls */
175
176 bool ACC (RW, plugincmd); // extend the protocol through a plug-in */
177 bool ACC (RW, mapinfocmd); // return map info and send map change info
178 uint8 ACC (RW, extcmd); // call into extensions/plugins
179 bool ACC (RW, need_delinv0); /* If true, we need to delinv 0 before sending new floorbox */
180
181 bool ACC (RW, update_look); /* If true, we need to send the look window */
182 bool ACC (RW, update_spells); // If true, we need to esrv_update_spells
183 bool ACC (RW, has_readable_type); /* If true client accept additional text information */
184 bool ACC (RW, monitor_spells); /* Client wishes to be informed when their spell list changes */
185
186 bool ACC (RW, smoothing); // deliantra-style smoothing
187 bool ACC (RW, force_newmap); // force a newmap before next map update
188 uint16 ACC (RW, look_position); /* start of drawing of look window */
189 uint16 ACC (RW, mss); // likely tcp maximum segment size
190 uint8 ACC (RW, mapx), ACC (RW, mapy); /* How large a map the client wants */
191 uint8 ACC (RW, itemcmd); /* What version of the 'item' protocol command to use */
192 uint8 ACC (RW, faceset); // CF+ selected faceset
193 uint8 ACC (RW, ws_version); // websocket protocol versio for framing
194
195 maptile_ptr ACC (RW, current_map); // CF+ last/current player map
196 region_ptr ACC (RW, current_region); // CF+ last/current player region
197 int ACC (RW, current_x), ACC (RW, current_y); // CF+ last/current map position
198
199 tstamp ACC (RW, last_send); // last data send on socket.
200
201 float ACC (RW, socket_timeout); /* after how many seconds of no ack do we declare dead */
202 int ACC (RW, rate_avail); // current rate balance
203 int ACC (RW, max_rate); // max. # of bytes to send per tick
204 faceidx ACC (RW, scrub_idx); // which face to send next
205 int ACC (RW, bg_scrub); // how many ticks till the next background face send
206
207 struct tcp_info tcpi;
208 tstamp next_rate_adjust;
209
210 // websocket frame buffer
211 uint8 ws_inbuf_type; // current frame type
212 uint8 *ws_inbuf;
213 uint32 ws_inbuf_len;
214 uint32 ws_inbuf_alloc;
215
216 unordered_vector<char *> mapinfo_queue;
217 void mapinfo_queue_clear ();
218 void mapinfo_queue_run ();
219 bool mapinfo_try (char *buf);
220
221 struct ixsend {
222 sint16 pri; // higher means faces are sent earlier, default 0
223 faceidx idx;
224 uint32 ofs; // if != 0, need to send remaining bytes of partial_face
225 uint8 *data;
226 SV *data_sv;
227 };
228 std::vector<ixsend, slice_allocator<ixsend> > ixface; // which faces to send to the client using ix
229 MTH void ix_send (faceidx idx, sint16 pri, SV *data_sv); // keeps a copy of data_sv
230 void ix_pop (); // pops topmost ixsend
231
232 std::vector<faceidx, slice_allocator<faceidx> > fxface; // which faces to send using fx
233 MTH void flush_fx (); // send fx if required
234
235 MTH void invalidate_face (faceidx idx);
236 MTH void invalidate_all_faces ();
237
238 void do_destroy ();
239 void gather_callbacks (AV *&callbacks, event_type event) const;
240
241 iow socket_ev; void socket_cb (iow &w, int revents);
242
243 std::deque< command, slice_allocator<command> > cmd_queue;
244
245 // large structures at the end please
108 struct Map lastmap; 246 struct Map lastmap;
109 size_t faces_sent_len; /* This is the number of elements allocated in faces_sent[] */ 247 std::bitset<MAXANIMNUM> anims_sent;
110 uint8 *faces_sent; /* This is a bitmap on sent face status */ 248 std::bitset<MAX_FACES> faces_sent;
111 uint8 anims_sent[MAXANIMNUM]; 249 std::bitset<FT_NUM> fx_want;
112 struct statsinfo stats;
113 250
114 char *ACC (RW, host); /* Which host it is connected from (ip address) */
115 uint8 ACC (RW, password_fails); /* how many times the player has failed to give the right password */
116 Buffer outputbuffer; /* For undeliverable data */
117
118 bool ACC (RW, facecache); /* If true, client is caching images */
119 bool ACC (RW, sent_scroll);
120 bool ACC (RW, sound); /* does the client want sound */
121 bool ACC (RW, exp64); /* Client wants 64 bit exp data, as well as skill data */
122 bool ACC (RW, newmapcmd); /* Send newmap command when entering new map SMACFIGGEN */
123 bool ACC (RW, plugincmd); /* CF+ extend the protocol through a plug-in */
124 bool ACC (RW, mapinfocmd); /* CF+ return map info and send map change info */
125 bool ACC (RW, extcmd); /* CF+ call into extensions/plugins */
126 bool ACC (RW, extmap); /* CF+ extend map comamnd with extra data */
127 bool ACC (RW, buggy_mapscroll); /* CF+ client crashes on large mapscrolls */
128 bool ACC (RW, darkness); /* True if client wants darkness information */
129 bool ACC (RW, image2); /* Client wants image2/face2 commands */
130 bool ACC (RW, update_look); /* If true, we need to send the look window */
131 bool ACC (RW, has_readable_type); /* If true client accept additional text information */
132 /* used to arrange text in books, scrolls, or scripted dialogs */
133 bool ACC (RW, monitor_spells); /* Client wishes to be informed when their spell list changes */
134 bool ACC (RW, ext_mapinfos); /* If true client accept additionnal info on maps */
135 /* Below are flags for extedend infos to pass to client
136 * with S->C mapextended command */
137 bool ACC (RW, EMI_smooth); /* Send smooth in extendmapinfos */
138
139 uint32 ACC (RW, supported_readables); /* each bit is a readable supported by client */
140 uint32 ACC (RW, cs_version), ACC (RW, sc_version); /* versions of the client */
141 enum MapMode mapmode; /* Type of map commands the client wants. */
142 uint16 ACC (RW, look_position); /* start of drawing of look window */
143 uint8 ACC (RW, mapx), ACC (RW, mapy); /* How large a map the client wants */
144 uint8 ACC (RW, itemcmd); /* What version of the 'item' protocol command to use */
145 uint8 ACC (RW, faceset); /* Set the client is using, default 0 */
146
147 maptile *ACC (RW, current_map); // CF+ last/current player map
148 int ACC (RW, current_x), ACC (RW, current_y); // CF+ last/current map position
149 char ACC (RW, version)[64]; // CF+ client name/version
150
151 /* If we get an incomplete packet, this is used to hold the data. */ 251 // if we get an incomplete packet, this is used to hold the data.
252 // we add 2 byte for the header, one for the trailing 0 byte
152 uint8 inbuf[MAXSOCKBUF]; 253 uint8 inbuf[MAXSOCKBUF + 2 + 1];
153 player *ACC (RO, pl);//TODO should not be here, preferably 254 void inbuf_handle ();
154 255
155 int ACC (RW, rtt), ACC (RW, rttvar); /* round-trip time and -variance, if known */ 256 enum { MSG_BUF_SIZE = 80, MSG_BUF_COUNT = 10 };
257 struct msg_buf
258 {
259 tick_t expire;
260 int len;
261 int count;
262 char msg[MSG_BUF_SIZE];
263 } msgbuf[MSG_BUF_COUNT];
156 264
157 iow socket_ev; void socket_cb (iow &w, int got); 265 MTH bool msg_suppressed (const_utf8_string msg);
158 266
267 /* The following is the setup for a ring buffer for storing output
268 * data that the OS can't handle right away.
269 * TODO: this member is enourmously large - optimise?
270 */
271 struct
272 {
273 char data[SOCKETBUFSIZE];
274 int start;
275 int len;
276 } outputbuffer;
277
278 bool may_execute (const packet_type *pkt) const;
279 void execute (const packet_type *pkt, char *data, int datalen);
280
281 void queue_command (packet_type *handler, char *data, int datalen);
282 MTH bool handle_command ();
283 // resets movement state
284 MTH void reset_state ();
285 // resets variable data used to send stat diffs
286 MTH void reset_stats ();
287
288 MTH bool handle_packet ();
289 int next_packet (); // returns length of packet or 0
290 void skip_packet (int len); // we have processed the packet, skip it
291
292 MTH void flush ();
293 MTH void write_outputbuffer ();
294 MTH int outputbuffer_len () const { return outputbuffer.len; }
295 void send_raw (void *buf_, int len);
296
297 void send (void *buf_, int len);
298 void send_packet (const_octet_string buf);
299 void send_packet (const_octet_string buf, int len);
300 void send_packet_printf (const_utf8_string format, ...) attribute ((format (printf, 2, 3)));
301 void send_packet (packet &sl);
302
303 void send_drawinfo (const_utf8_string msg, int flags = NDI_BLACK);
304
305 MTH void send_face (faceidx facenum, int pri = 0);
306 MTH void send_faces (object *ob);
307 MTH void send_animation (short anim_num);
308 void send_msg (int color, const_utf8_string type, const_utf8_string msg);
309
310 MTH void play_sound (faceidx sound, int dx = 0, int dy = 0);
311 // called when something under the player changes
312 MTH void floorbox_update () { update_look = 1; }
313 // called when the player has been moved
314 MTH void floorbox_reset () { look_position = 0; floorbox_update (); }
315
316 MTH void tick (); // called every server tick to do housekeeping etc.
317
318 MTH static client *create (int fd, const char *peername);
319 MTH static void clock ();
320 MTH static void flush_sockets ();
321
322 MTH void run (); // start handshake after init
323
324protected:
159 client (int fd, const char *from_ip); 325 client (int fd, const char *from_ip);
160 ~client (); 326 ~client ();
161
162 int read_packet (); // returns length of packet or 0
163 void skip_packet (int len); // we have processed the packet, skip it
164
165 void flush ();
166 void write_outputbuffer ();
167 void send (void *buf_, int len);
168
169 void send_packet (const char *buf);
170 void send_packet (const char *buf, int len);
171 void send_packet (packet &sl);
172}; 327};
173 328
174#define CLIENT_SUPPORT_READABLES(__sockPtr,__type)\ 329#if FOR_PERL
175 ( ((__type)>0) &&\ 330 ACC (RW, tcpi.tcpi_state);
176 ((__sockPtr)->has_readable_type) && \ 331 ACC (RW, tcpi.tcpi_ca_state);
177 ((__sockPtr)->supported_readables & (1<<(__type))) ) 332 ACC (RW, tcpi.tcpi_retransmits);
333 ACC (RW, tcpi.tcpi_probes);
334 ACC (RW, tcpi.tcpi_backoff);
335 ACC (RW, tcpi.tcpi_options);
336 ACC (RO, tcpi.tcpi_snd_wscale);
337 ACC (RO, tcpi.tcpi_rcv_wscale);
338 ACC (RW, tcpi.tcpi_rto);
339 ACC (RW, tcpi.tcpi_ato);
340 ACC (RW, tcpi.tcpi_snd_mss);
341 ACC (RW, tcpi.tcpi_rcv_mss);
342 ACC (RW, tcpi.tcpi_unacked);
343 ACC (RW, tcpi.tcpi_sacked);
344 ACC (RW, tcpi.tcpi_lost);
345 ACC (RW, tcpi.tcpi_retrans);
346 ACC (RW, tcpi.tcpi_fackets);
347 ACC (RW, tcpi.tcpi_last_data_sent);
348 ACC (RW, tcpi.tcpi_last_ack_sent);
349 ACC (RW, tcpi.tcpi_last_data_recv);
350 ACC (RW, tcpi.tcpi_last_ack_recv);
351 ACC (RW, tcpi.tcpi_pmtu);
352 ACC (RW, tcpi.tcpi_rcv_ssthresh);
353 ACC (RW, tcpi.tcpi_rtt);
354 ACC (RW, tcpi.tcpi_rttvar);
355 ACC (RW, tcpi.tcpi_snd_ssthresh);
356 ACC (RW, tcpi.tcpi_snd_cwnd);
357 ACC (RW, tcpi.tcpi_advmss);
358 ACC (RW, tcpi.tcpi_reordering);
359#endif
178 360
179/* Bitmask for the faces_sent[] array - what 361typedef object_vector<client, &client::active> sockvec;
180 * portion of the face have we sent?
181 */
182#define NS_FACESENT_FACE 0x1
183#define NS_FACESENT_SMOOTH 0x2
184
185/* Constants in the form EMI_ is for extended map infos.
186 * Even if the client select the additionnal infos it wants
187 * on the map, there may exist cases where this whole info
188 * is not given in one buch but in separate bunches. This
189 * is done performance reasons (imagine some info related to
190 * a visible object and another info related to a 4 square
191 * width and height area). At the begin of an extended info packet
192 * is a bit field. A bit is activated for each extended info
193 * present in the data
194 */
195
196/* Meanings:
197 * EMI_NOREDRAW Take extended infos into account but don't redraw,
198 * some additionnal datas will follow in a new packet
199 * EMI_SMOOTH Datas about smoothing
200 */
201#define EMI_NOREDRAW 0x01
202#define EMI_SMOOTH 0x02
203
204/* this last one says the bitfield continue un next byte
205 * There may be several on contiguous bytes. So there is 7
206 * actual bits used per byte, and the number of bytes
207 * is not fixed in protocol
208 */
209#define EMI_HASMOREBITS 0x80
210
211#define FACE_TYPES 1
212#define PNG_FACE_INDEX 0
213
214#define VERSION_CS 1023 /* version >= 1023 understand setup cmd */
215#define VERSION_SC 1027
216#define VERSION_INFO "Crossfire+ Server"
217
218typedef unordered_vector<client *> sockvec;
219 362
220extern sockvec clients; 363extern sockvec clients;
221extern int nrofpixmaps; //TODO: hrmpf, should go 364
365#define for_all_clients(var) \
366 for (int _i = 0; _i < clients.size (); ++_i) \
367 statementvar (client *, var, clients [_i])
368
369// returns true when the message needs special (read: perl) treatment
370static inline bool
371msg_is_special (const_any_string msg, bool nl_special = true)
372{
373 return msg [strcspn (msg, nl_special ? "<&\n" : "<&")];
374}
222 375
223#endif 376#endif
224 377

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines