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.1 by root, Fri Dec 15 19:59:19 2006 UTC vs.
Revision 1.55 by root, Sun Jun 24 04:09:29 2007 UTC

1
2/* 1/*
3 CrossFire, A Multiplayer game for the X Window System 2 * This file is part of Crossfire TRT, the Multiplayer Online Role Playing Game.
4 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software; you can redistribute it and/or modify it
9 it under the terms of the GNU General Public License as published by 9 * under the terms of the GNU General Public License as published by the Free
10 the Free Software Foundation; either version 2 of the License, or 10 * Software Foundation; either version 2 of the License, or (at your option)
11 (at your option) any later version. 11 * any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful, but
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 GNU General Public License for more details. 16 * for more details.
17 17 *
18 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License along
19 along with this program; if not, write to the Free Software 19 * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 21 *
22 The author can be reached via e-mail to crossfire-devel@real-time.com 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
23*/ 23 */
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 24
32#ifndef CLIENT_H 25#ifndef CLIENT_H
33#define CLIENT_H 26#define CLIENT_H
34 27
35/* Reduce this from 50 to 5 - as it is now, there will never be more 28#include <deque>
36 * than 3 anyways. 29#include <bitset>
37 */ 30#include <tr1/unordered_set>
38 31
39#define NUM_LOOK_OBJECTS 50 32// (possibly) max. number of objects "per page" in the ground container
33#define FLOORBOX_PAGESIZE 50
40 34
41struct MapCell 35struct MapCell
42{ 36{
43 UUID player; // this is, unfortunately, very wasteful of memory space, but pretty bandwidth-efficient 37 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 */ 38 int count; /* This is really darkness in the map1 command */
45 uint16 faces[MAP_LAYERS]; 39 faceidx faces[MAP_LAYERS];
46 uint16 smooth[MAP_LAYERS];
47 unsigned char stat_hp; // health of something in this space, or 0 40 unsigned char stat_hp; // health of something in this space, or 0
48 unsigned char flags; 41 unsigned char flags;
42 uint8_t smooth[MAP_LAYERS];
49}; 43};
50 44
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) 45#define MAX_CLIENT_X MAP_CLIENT_X
59#define MAX_CLIENT_Y (MAP_CLIENT_Y + MAX_HEAD_OFFSET) 46#define MAX_CLIENT_Y MAP_CLIENT_Y
60 47
61struct Map 48struct Map
62{ 49{
63 struct MapCell cells[MAX_CLIENT_X][MAX_CLIENT_Y]; 50 struct MapCell cells[MAX_CLIENT_X][MAX_CLIENT_Y];
64}; 51};
65 52
66/* True max is 16383 given current map compaction method */ 53/* True max is 16383 given current map compaction method */
67# define MAXANIMNUM 2000 54#define MAXANIMNUM 10000
68 55
69struct statsinfo 56struct statsinfo
70{ 57{
71 char *range, *title; 58 char *range, *title;
72}; 59};
75 * current state. we set up our on buffers for sending/receiving, so we can 62 * 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 63 * handle some higher level functions. fd is the actual file descriptor we
77 * are using. 64 * are using.
78 */ 65 */
79 66
80enum Sock_Status { Ns_Add, Ns_Dead };
81
82/* Only one map mode can actually be used, so lets make it a switch 67/* 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 68 * instead of having a bunch of different fields that needed to
84 * get toggled. 69 * get toggled.
85 */ 70 */
86enum MapMode { Map0Cmd = 0, Map1Cmd = 1, Map1aCmd = 2 }; 71enum { Map0Cmd = 0, Map1Cmd = 1, Map1aCmd = 2 };
87 72
88/* The following is the setup for a ring buffer for storing outbut 73// states the socket can be in
89 * data that the OS can't handle right away. 74enum {
90 */ 75 ST_DEAD, // socket is dead
76 ST_SETUP, // initial handshake / setup / login
77 ST_PLAYING, // logged in an playing
78 ST_CUSTOM, // waiting for custom reply
91 79
92struct Buffer 80 ST_GET_PARTY_PASSWORD,
81};
82
83// a handler for a specific type of packet
84enum {
85 PF_PLAYER = 0x01, // must have valid player / will by synchronised
86 PF_PLAYING = 0x02, // must be in playing state
87 PF_COMMAND0 = 0x04, // command starts at offset 0
88 PF_COMMAND6 = 0x08, // command starts at offset 6
89};
90
91struct packet_type
93{ 92{
94 char data[SOCKETBUFSIZE]; 93 const char *name;
95 int start; 94 void *cb;
95 int flags;
96};
97
98struct command
99{
100 tstamp stamp;
101 const packet_type *handler;
102 char *data;
96 int len; 103 int datalen;
104
105 ~command ()
106 {
107 sfree<char> (data, datalen + 1);
108 }
97}; 109};
98 110
99/* how many times we are allowed to give the wrong password before being kicked. */ 111/* how many times we are allowed to give the wrong password before being kicked. */
100#define MAX_PASSWORD_FAILURES 5 112#define MAX_PASSWORD_FAILURES 5
101 113
102ACC_CLASS (client) // should become player when newsocket is a baseclass of player 114INTERFACE_CLASS (client) // should become player when newsocket is a baseclass of player
103struct client : zero_initialised, attachable_base 115struct client : zero_initialised, attachable
104{ 116{
105 enum Sock_Status status;
106 int ACC (RW, fd); 117 int ACC (RW, fd);
107 unsigned int inbuf_len; // number of bytes valid in inbuf 118 unsigned int inbuf_len; // number of bytes valid in inbuf
108 struct Map lastmap;
109 size_t faces_sent_len; /* This is the number of elements allocated in faces_sent[] */
110 uint8 *faces_sent; /* This is a bitmap on sent face status */
111 uint8 anims_sent[MAXANIMNUM];
112 struct statsinfo stats; 119 statsinfo stats;
120 object_vector_index ACC (RO, active);
121 player_ptr ACC (RO, pl);
122
123 /* The following is the setup for a ring buffer for storing output
124 * data that the OS can't handle right away.
125 */
126 struct
127 {
128 char data[SOCKETBUFSIZE];
129 int start;
130 int len;
131 } outputbuffer;
113 132
114 char *ACC (RW, host); /* Which host it is connected from (ip address) */ 133 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 */ 134 uint8 ACC (RW, state); /* Input state of the player (name, password, etc */
116 Buffer outputbuffer; /* For undeliverable data */
117 135
136 sint8 ACC (RW, last_level); /* Last level we sent to client */
137 uint16 ACC (RW, last_flags); /* fire/run on flags for last tick */
138 float ACC (RW, last_weapon_sp); /* if diff than weapon_sp, update client */
139 sint32 ACC (RW, last_weight); /* Last weight as sent to client; -1 means do not send weight */
140 sint32 ACC (RW, last_weight_limit); /* Last weight limit transmitted to client */
141 uint32 ACC (RW, last_path_attuned); /* Last spell attunment sent to client */
142 uint32 ACC (RW, last_path_repelled); /* Last spell repelled sent to client */
143 uint32 ACC (RW, last_path_denied); /* Last spell denied sent to client */
144 living ACC (RO, last_stats); /* Last stats as sent to client */
145 float ACC (RW, last_speed); /* Last speed as sent to client */
146 sint16 ACC (RW, last_resist[NROFATTACKS]);/* last resist values sent to client */
147 sint64 ACC (RW, last_skill_exp[NUM_SKILLS]);/* shadow register. if != exp. obj update client */
148
149 bool ACC (RW, force_face0); // client workaround for buggy checksum calculation in gcfclient
150 bool ACC (RW, force_bad_checksum); // client workaround for buggy checksum calculation in gcfclient
151 bool ACC (RW, force_image_newmap); // client workaround for client not redrawing map on image upload
152 bool ACC (RW, enable_bg_scrub); // client workaround, gcfclient becomes unusable if you send it images
153
154 bool ACC (RW, afk); /* player is afk */
118 bool ACC (RW, facecache); /* If true, client is caching images */ 155 bool ACC (RW, facecache); /* If true, client is caching images */
119 bool ACC (RW, sent_scroll); 156 bool ACC (RW, sent_scroll);
120 bool ACC (RW, sound); /* does the client want sound */ 157 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 */ 158 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 */ 159 bool ACC (RW, plugincmd); // extend the protocol through a plug-in */
124 bool ACC (RW, mapinfocmd); /* CF+ return map info and send map change info */ 160 bool ACC (RW, mapinfocmd); // return map info and send map change info
125 bool ACC (RW, extcmd); /* CF+ call into extensions/plugins */ 161 bool ACC (RW, extcmd); // call into extensions/plugins
126 bool ACC (RW, extmap); /* CF+ extend map comamnd with extra data */ 162 bool ACC (RW, extmap); // extend map comamnd with extra data
127 bool ACC (RW, buggy_mapscroll); /* CF+ client crashes on large mapscrolls */ 163 bool ACC (RW, buggy_mapscroll); // client crashes on large mapscrolls
128 bool ACC (RW, darkness); /* True if client wants darkness information */ 164 bool ACC (RW, darkness); /* True if client wants darkness information */
129 bool ACC (RW, image2); /* Client wants image2/face2 commands */ 165 bool ACC (RW, image2); /* Client wants image2/face2 commands */
166 bool ACC (RW, fxix); // client implements fx and ix (face|image extended) commands
130 bool ACC (RW, update_look); /* If true, we need to send the look window */ 167 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 */ 168 bool ACC (RW, has_readable_type); /* If true client accept additional text information */
132 /* used to arrange text in books, scrolls, or scripted dialogs */ 169 /* 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 */ 170 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 */ 171 bool ACC (RW, ext_mapinfos); /* If true client accepts additional info on maps */
135 /* Below are flags for extedend infos to pass to client 172 /* Below are flags for extedend infos to pass to client
136 * with S->C mapextended command */ 173 * with S->C mapextended command */
137 bool ACC (RW, EMI_smooth); /* Send smooth in extendmapinfos */ 174 bool ACC (RW, EMI_smooth); /* Send smooth in extendmapinfos */
175 bool ACC (RW, smoothing); // trt-style smoothing
176 bool ACC (RW, can_msg); // trt-style text messages
138 177
178 bool ACC (RW, force_newmap); // force a newmap before next map update
139 uint32 ACC (RW, supported_readables); /* each bit is a readable supported by client */ 179 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 */ 180 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 */ 181 uint16 ACC (RW, look_position); /* start of drawing of look window */
182 uint16 ACC (RW, mss); // likely tcp maximum segment size
183 uint8 ACC (RW, mapmode); /* Type of map commands the client wants. */
143 uint8 ACC (RW, mapx), ACC (RW, mapy); /* How large a map the client wants */ 184 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 */ 185 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 186
147 maptile *ACC (RW, current_map); // CF+ last/current player map 187 maptile *ACC (RW, current_map); // CF+ last/current player map
188 region *ACC (RW, current_region); // CF+ last/current player region
148 int ACC (RW, current_x), ACC (RW, current_y); // CF+ last/current map position 189 int ACC (RW, current_x), ACC (RW, current_y); // CF+ last/current map position
149 char ACC (RW, version)[64]; // CF+ client name/version 190 shstr ACC (RW, version); // CF+ client name/version
191 uint8 ACC (RW, faceset); // CF+ selected faceset
150 192
151 /* If we get an incomplete packet, this is used to hold the data. */ 193 tstamp ACC (RW, last_send); // last data send on socket.
152 uint8 inbuf[MAXSOCKBUF];
153 player *ACC (RO, pl);//TODO should not be here, preferably
154 194
155 int ACC (RW, rtt), ACC (RW, rttvar); /* round-trip time and -variance, if known */ 195 int ACC (RW, rtt), ACC (RW, rttvar); /* round-trip time and -variance, if known */
196
197 int ACC (RW, rate_avail); // current rate balance
198 int ACC (RW, max_rate); // max. # of bytes to send per tick
199 faceidx ACC (RW, scrub_idx); // which face to send next
200 int ACC (RW, bg_scrub); // how many ticks till the next background face send
201
202 faceidx partial_face;
203 uint32 partial_face_ofs; // if != 0, need to send remaining bytes of partial_face
204 std::vector<faceidx, slice_allocator<faceidx> > askface; // which faces have been requested by the client
205
206 std::vector<faceidx, slice_allocator<faceidx> > fxface; // which faces to send using fx
207 MTH void flush_fx (); // send fx if required
208
209 void do_destroy ();
210 void gather_callbacks (AV *&callbacks, event_type event) const;
156 211
157 iow socket_ev; void socket_cb (iow &w, int got); 212 iow socket_ev; void socket_cb (iow &w, int got);
213 iw cmd_ev; void cmd_cb (iw &w);
158 214
215 std::deque< command, slice_allocator<command> > cmd_queue;
216
217 // large structures at the end please
218 struct Map lastmap;
219 std::bitset<MAXANIMNUM> anims_sent;
220 std::bitset<MAX_FACES> faces_sent;
221
222 // if we get an incomplete packet, this is used to hold the data.
223 // we add 2 byte for the header, one for the trailing 0 byte
224 uint8 inbuf[MAXSOCKBUF + 2 + 1];
225
226 enum { MSG_BUF_SIZE = 80, MSG_BUF_COUNT = 10 };
227 struct msg_buf
228 {
229 tick_t expire;
230 int len;
231 int count;
232 char msg[MSG_BUF_SIZE];
233 } msgbuf[MSG_BUF_COUNT];
234
235 MTH bool msg_suppressed (const char *msg);
236
237 bool may_execute (const packet_type *pkt) const;
238 void execute (const packet_type *pkt, char *data, int datalen);
239
240 void queue_command (packet_type *handler, char *data, int datalen);
241 MTH bool handle_command ();
242 // resets movement state
243 MTH void reset_state ();
244 // resets variable data used to send stat diffs
245 MTH void reset_stats ();
246
247 MTH bool handle_packet ();
248 int next_packet (); // returns length of packet or 0
249 void skip_packet (int len); // we have processed the packet, skip it
250
251 MTH void flush ();
252 MTH void write_outputbuffer ();
253 MTH int outputbuffer_len () const { return outputbuffer.len; }
254 void send (void *buf_, int len);
255
256 void send_packet (const char *buf);
257 void send_packet (const char *buf, int len);
258 void send_packet_printf (const char *format, ...);
259 void send_packet (packet &sl);
260
261 void send_drawinfo (const char *msg, int flags = NDI_BLACK);
262 MTH void send_face (faceidx facenum);
263 MTH void send_image (faceidx facenum);
264 MTH void send_faces (object *ob);
265 MTH void send_animation (short anim_num);
266 void send_msg (int color, const char *type, const char *msg);
267
268 // called when something under the player changes
269 MTH void floorbox_update () { update_look = 1; }
270 // called when the player has been moved
271 MTH void floorbox_reset () { look_position = 0; floorbox_update (); }
272
273 MTH void tick (); // called every server tick to do housekeeping etc.
274
275 MTH static client *create (int fd, const char *peername);
276
277protected:
159 client (int fd, const char *from_ip); 278 client (int fd, const char *from_ip);
160 ~client (); 279 ~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}; 280};
173 281
174#define CLIENT_SUPPORT_READABLES(__sockPtr,__type)\ 282#define CLIENT_SUPPORT_READABLES(__sockPtr,__type)\
175 ( ((__type)>0) &&\ 283 ( ((__type)>0) &&\
176 ((__sockPtr)->has_readable_type) && \ 284 ((__sockPtr)->has_readable_type) && \
177 ((__sockPtr)->supported_readables & (1<<(__type))) ) 285 ((__sockPtr)->supported_readables & (1<<(__type))) )
178
179/* Bitmask for the faces_sent[] array - what
180 * portion of the face have we sent?
181 */
182#define NS_FACESENT_FACE 0x1
183#define NS_FACESENT_SMOOTH 0x2
184 286
185/* Constants in the form EMI_ is for extended map infos. 287/* Constants in the form EMI_ is for extended map infos.
186 * Even if the client select the additionnal infos it wants 288 * Even if the client select the additionnal infos it wants
187 * on the map, there may exist cases where this whole info 289 * on the map, there may exist cases where this whole info
188 * is not given in one buch but in separate bunches. This 290 * is not given in one buch but in separate bunches. This
210 312
211#define FACE_TYPES 1 313#define FACE_TYPES 1
212#define PNG_FACE_INDEX 0 314#define PNG_FACE_INDEX 0
213 315
214#define VERSION_CS 1023 /* version >= 1023 understand setup cmd */ 316#define VERSION_CS 1023 /* version >= 1023 understand setup cmd */
215#define VERSION_SC 1027 317#define VERSION_SC 1026
318//#define VERSION_SC 1027 // requestinfo image_info and image_sums, makes extending faces on the fly impossible
216#define VERSION_INFO "Crossfire+ Server" 319#define VERSION_INFO "Crossfire+ Server"
217 320
218typedef unordered_vector<client *> sockvec; 321typedef object_vector<client, &client::active> sockvec;
219 322
220extern sockvec clients; 323extern sockvec clients;
221extern int nrofpixmaps; //TODO: hrmpf, should go 324
325#define for_all_clients(var) \
326 for (int _i = 0; _i < clients.size (); ++_i) \
327 statementvar (client *, var, clients [_i])
222 328
223#endif 329#endif
224 330

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines