ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/client.h
Revision: 1.59
Committed: Sun Jul 1 05:00:18 2007 UTC (16 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.58: +11 -12 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# User Rev Content
1 root 1.1 /*
2 root 1.59 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 pippijn 1.26 *
4 root 1.51 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5     * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992,2007 Frank Tore Johansen
7 pippijn 1.26 *
8 root 1.59 * Crossfire TRT 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 3 of the License, or
11     * (at your option) any later version.
12 pippijn 1.26 *
13 root 1.59 * 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 pippijn 1.26 *
18 root 1.59 * You should have received a copy of the GNU General Public License
19     * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 root 1.51 *
21     * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 pippijn 1.26 */
23 root 1.1
24     #ifndef CLIENT_H
25     #define CLIENT_H
26    
27 root 1.4 #include <deque>
28 root 1.7 #include <bitset>
29 root 1.13 #include <tr1/unordered_set>
30 root 1.1
31 root 1.4 // (possibly) max. number of objects "per page" in the ground container
32 root 1.11 #define FLOORBOX_PAGESIZE 50
33 root 1.1
34     struct MapCell
35     {
36 root 1.47 tag_t player; // this is, unfortunately, very wasteful of memory space, but pretty bandwidth-efficient
37 root 1.37 int count; /* This is really darkness in the map1 command */
38 root 1.32 faceidx faces[MAP_LAYERS];
39 root 1.36 unsigned char stat_hp; // health of something in this space, or 0
40 root 1.1 unsigned char flags;
41 root 1.37 uint8_t smooth[MAP_LAYERS];
42 root 1.1 };
43    
44 root 1.33 #define MAX_CLIENT_X MAP_CLIENT_X
45     #define MAX_CLIENT_Y MAP_CLIENT_Y
46 root 1.1
47     struct Map
48     {
49     struct MapCell cells[MAX_CLIENT_X][MAX_CLIENT_Y];
50     };
51    
52     /* True max is 16383 given current map compaction method */
53 root 1.33 #define MAXANIMNUM 10000
54 root 1.1
55     struct statsinfo
56     {
57     char *range, *title;
58     };
59    
60     /* This contains basic information on the socket structure. status is its
61     * current state. we set up our on buffers for sending/receiving, so we can
62     * handle some higher level functions. fd is the actual file descriptor we
63     * are using.
64     */
65    
66     /* Only one map mode can actually be used, so lets make it a switch
67     * instead of having a bunch of different fields that needed to
68     * get toggled.
69     */
70 root 1.42 enum { Map0Cmd = 0, Map1Cmd = 1, Map1aCmd = 2 };
71 root 1.1
72 root 1.15 // states the socket can be in
73     enum {
74     ST_DEAD, // socket is dead
75     ST_SETUP, // initial handshake / setup / login
76     ST_PLAYING, // logged in an playing
77     ST_CUSTOM, // waiting for custom reply
78    
79     ST_GET_PARTY_PASSWORD,
80     };
81    
82 root 1.4 // a handler for a specific type of packet
83     enum {
84 root 1.28 PF_PLAYER = 0x01, // must have valid player / will by synchronised
85     PF_PLAYING = 0x02, // must be in playing state
86     PF_COMMAND0 = 0x04, // command starts at offset 0
87     PF_COMMAND6 = 0x08, // command starts at offset 6
88 root 1.4 };
89    
90     struct packet_type
91     {
92     const char *name;
93     void *cb;
94     int flags;
95     };
96    
97     struct command
98     {
99     tstamp stamp;
100     const packet_type *handler;
101     char *data;
102     int datalen;
103    
104 root 1.6 ~command ()
105 root 1.4 {
106 root 1.8 sfree<char> (data, datalen + 1);
107 root 1.4 }
108     };
109    
110 root 1.1 /* how many times we are allowed to give the wrong password before being kicked. */
111     #define MAX_PASSWORD_FAILURES 5
112    
113 root 1.21 INTERFACE_CLASS (client) // should become player when newsocket is a baseclass of player
114     struct client : zero_initialised, attachable
115 root 1.1 {
116     int ACC (RW, fd);
117 root 1.10 unsigned int inbuf_len; // number of bytes valid in inbuf
118 root 1.20 statsinfo stats;
119 root 1.54 object_vector_index ACC (RO, active);
120 root 1.53 player_ptr ACC (RO, pl);
121 root 1.12
122 root 1.49 /* The following is the setup for a ring buffer for storing output
123     * data that the OS can't handle right away.
124     */
125     struct
126     {
127     char data[SOCKETBUFSIZE];
128     int start;
129     int len;
130     } outputbuffer;
131 root 1.10
132     char *ACC (RW, host); /* Which host it is connected from (ip address) */
133 root 1.15 uint8 ACC (RW, state); /* Input state of the player (name, password, etc */
134 root 1.25
135     sint8 ACC (RW, last_level); /* Last level we sent to client */
136     uint16 ACC (RW, last_flags); /* fire/run on flags for last tick */
137     float ACC (RW, last_weapon_sp); /* if diff than weapon_sp, update client */
138     sint32 ACC (RW, last_weight); /* Last weight as sent to client; -1 means do not send weight */
139     sint32 ACC (RW, last_weight_limit); /* Last weight limit transmitted to client */
140     uint32 ACC (RW, last_path_attuned); /* Last spell attunment sent to client */
141     uint32 ACC (RW, last_path_repelled); /* Last spell repelled sent to client */
142     uint32 ACC (RW, last_path_denied); /* Last spell denied sent to client */
143     living ACC (RO, last_stats); /* Last stats as sent to client */
144     float ACC (RW, last_speed); /* Last speed as sent to client */
145     sint16 ACC (RW, last_resist[NROFATTACKS]);/* last resist values sent to client */
146     sint64 ACC (RW, last_skill_exp[NUM_SKILLS]);/* shadow register. if != exp. obj update client */
147 root 1.10
148 root 1.42 bool ACC (RW, force_face0); // client workaround for buggy checksum calculation in gcfclient
149     bool ACC (RW, force_bad_checksum); // client workaround for buggy checksum calculation in gcfclient
150     bool ACC (RW, force_image_newmap); // client workaround for client not redrawing map on image upload
151     bool ACC (RW, enable_bg_scrub); // client workaround, gcfclient becomes unusable if you send it images
152    
153 root 1.20 bool ACC (RW, afk); /* player is afk */
154 root 1.10 bool ACC (RW, facecache); /* If true, client is caching images */
155     bool ACC (RW, sent_scroll);
156     bool ACC (RW, sound); /* does the client want sound */
157     bool ACC (RW, newmapcmd); /* Send newmap command when entering new map SMACFIGGEN */
158 root 1.40 bool ACC (RW, plugincmd); // extend the protocol through a plug-in */
159     bool ACC (RW, mapinfocmd); // return map info and send map change info
160     bool ACC (RW, extcmd); // call into extensions/plugins
161     bool ACC (RW, extmap); // extend map comamnd with extra data
162     bool ACC (RW, buggy_mapscroll); // client crashes on large mapscrolls
163 root 1.10 bool ACC (RW, darkness); /* True if client wants darkness information */
164     bool ACC (RW, image2); /* Client wants image2/face2 commands */
165 root 1.57 uint8_t ACC (RW, fxix); // client implements fx and ix (face|image extended) commands
166 root 1.10 bool ACC (RW, update_look); /* If true, we need to send the look window */
167     bool ACC (RW, has_readable_type); /* If true client accept additional text information */
168     /* used to arrange text in books, scrolls, or scripted dialogs */
169     bool ACC (RW, monitor_spells); /* Client wishes to be informed when their spell list changes */
170     bool ACC (RW, ext_mapinfos); /* If true client accepts additional info on maps */
171     /* Below are flags for extedend infos to pass to client
172     * with S->C mapextended command */
173     bool ACC (RW, EMI_smooth); /* Send smooth in extendmapinfos */
174 root 1.48 bool ACC (RW, smoothing); // trt-style smoothing
175     bool ACC (RW, can_msg); // trt-style text messages
176 root 1.1
177 root 1.40 bool ACC (RW, force_newmap); // force a newmap before next map update
178 root 1.1 uint32 ACC (RW, supported_readables); /* each bit is a readable supported by client */
179     uint32 ACC (RW, cs_version), ACC (RW, sc_version); /* versions of the client */
180     uint16 ACC (RW, look_position); /* start of drawing of look window */
181 root 1.43 uint16 ACC (RW, mss); // likely tcp maximum segment size
182 root 1.42 uint8 ACC (RW, mapmode); /* Type of map commands the client wants. */
183 root 1.1 uint8 ACC (RW, mapx), ACC (RW, mapy); /* How large a map the client wants */
184     uint8 ACC (RW, itemcmd); /* What version of the 'item' protocol command to use */
185    
186     maptile *ACC (RW, current_map); // CF+ last/current player map
187 root 1.29 region *ACC (RW, current_region); // CF+ last/current player region
188 root 1.1 int ACC (RW, current_x), ACC (RW, current_y); // CF+ last/current map position
189 root 1.49 shstr ACC (RW, version); // CF+ client name/version
190 root 1.32 uint8 ACC (RW, faceset); // CF+ selected faceset
191 root 1.1
192 root 1.53 tstamp ACC (RW, last_send); // last data send on socket.
193 root 1.1
194 root 1.38 int ACC (RW, rtt), ACC (RW, rttvar); /* round-trip time and -variance, if known */
195    
196 root 1.44 int ACC (RW, rate_avail); // current rate balance
197 root 1.38 int ACC (RW, max_rate); // max. # of bytes to send per tick
198 root 1.39 faceidx ACC (RW, scrub_idx); // which face to send next
199     int ACC (RW, bg_scrub); // how many ticks till the next background face send
200 root 1.45
201 root 1.58 struct ixsend {
202     int16_t pri; // unused
203     faceidx idx;
204     uint32_t ofs; // if != 0, need to send remaining bytes of partial_face
205     };
206     std::vector<ixsend, slice_allocator<ixsend> > ixface; // which faces to send to the client using ix
207 root 1.45
208 root 1.57 std::vector<faceidx, slice_allocator<faceidx> > fxface; // which faces to send using fx
209 root 1.45 MTH void flush_fx (); // send fx if required
210 root 1.1
211 root 1.21 void do_destroy ();
212     void gather_callbacks (AV *&callbacks, event_type event) const;
213 root 1.4
214 pippijn 1.30 iow socket_ev; void socket_cb (iow &w, int got);
215 root 1.4 iw cmd_ev; void cmd_cb (iw &w);
216 root 1.1
217 root 1.4 std::deque< command, slice_allocator<command> > cmd_queue;
218    
219 root 1.14 // large structures at the end please
220     struct Map lastmap;
221     std::bitset<MAXANIMNUM> anims_sent;
222 root 1.36 std::bitset<MAX_FACES> faces_sent;
223    
224 root 1.14 // if we get an incomplete packet, this is used to hold the data.
225     // we add 2 byte for the header, one for the trailing 0 byte
226     uint8 inbuf[MAXSOCKBUF + 2 + 1];
227    
228 root 1.49 enum { MSG_BUF_SIZE = 80, MSG_BUF_COUNT = 10 };
229     struct msg_buf
230     {
231     tick_t expire;
232     int len;
233     int count;
234     char msg[MSG_BUF_SIZE];
235     } msgbuf[MSG_BUF_COUNT];
236    
237     MTH bool msg_suppressed (const char *msg);
238    
239 root 1.4 bool may_execute (const packet_type *pkt) const;
240     void execute (const packet_type *pkt, char *data, int datalen);
241    
242     void queue_command (packet_type *handler, char *data, int datalen);
243 root 1.22 MTH bool handle_command ();
244 root 1.14 // resets movement state
245 root 1.22 MTH void reset_state ();
246 root 1.25 // resets variable data used to send stat diffs
247     MTH void reset_stats ();
248 root 1.1
249 root 1.22 MTH bool handle_packet ();
250 root 1.4 int next_packet (); // returns length of packet or 0
251 root 1.1 void skip_packet (int len); // we have processed the packet, skip it
252    
253 root 1.22 MTH void flush ();
254     MTH void write_outputbuffer ();
255 root 1.38 MTH int outputbuffer_len () const { return outputbuffer.len; }
256 root 1.1 void send (void *buf_, int len);
257    
258     void send_packet (const char *buf);
259     void send_packet (const char *buf, int len);
260 root 1.4 void send_packet_printf (const char *format, ...);
261 root 1.1 void send_packet (packet &sl);
262 root 1.7
263 root 1.35 void send_drawinfo (const char *msg, int flags = NDI_BLACK);
264 root 1.38 MTH void send_face (faceidx facenum);
265     MTH void send_image (faceidx facenum);
266 root 1.35 MTH void send_faces (object *ob);
267     MTH void send_animation (short anim_num);
268 root 1.55 void send_msg (int color, const char *type, const char *msg);
269 root 1.35
270 root 1.10 // called when something under the player changes
271 root 1.22 MTH void floorbox_update () { update_look = 1; }
272 root 1.10 // called when the player has been moved
273 root 1.22 MTH void floorbox_reset () { look_position = 0; floorbox_update (); }
274    
275 root 1.39 MTH void tick (); // called every server tick to do housekeeping etc.
276    
277 root 1.22 MTH static client *create (int fd, const char *peername);
278 root 1.10
279 root 1.22 protected:
280     client (int fd, const char *from_ip);
281     ~client ();
282 root 1.1 };
283    
284     #define CLIENT_SUPPORT_READABLES(__sockPtr,__type)\
285     ( ((__type)>0) &&\
286     ((__sockPtr)->has_readable_type) && \
287     ((__sockPtr)->supported_readables & (1<<(__type))) )
288    
289     /* Constants in the form EMI_ is for extended map infos.
290     * Even if the client select the additionnal infos it wants
291     * on the map, there may exist cases where this whole info
292     * is not given in one buch but in separate bunches. This
293     * is done performance reasons (imagine some info related to
294     * a visible object and another info related to a 4 square
295     * width and height area). At the begin of an extended info packet
296     * is a bit field. A bit is activated for each extended info
297     * present in the data
298     */
299    
300     /* Meanings:
301     * EMI_NOREDRAW Take extended infos into account but don't redraw,
302     * some additionnal datas will follow in a new packet
303     * EMI_SMOOTH Datas about smoothing
304     */
305     #define EMI_NOREDRAW 0x01
306     #define EMI_SMOOTH 0x02
307    
308     /* this last one says the bitfield continue un next byte
309     * There may be several on contiguous bytes. So there is 7
310     * actual bits used per byte, and the number of bytes
311     * is not fixed in protocol
312     */
313     #define EMI_HASMOREBITS 0x80
314    
315     #define FACE_TYPES 1
316     #define PNG_FACE_INDEX 0
317    
318     #define VERSION_CS 1023 /* version >= 1023 understand setup cmd */
319 root 1.31 #define VERSION_SC 1026
320     //#define VERSION_SC 1027 // requestinfo image_info and image_sums, makes extending faces on the fly impossible
321 root 1.56 #define VERSION_INFO "Crossfire TRT Server"
322 root 1.1
323 root 1.24 typedef object_vector<client, &client::active> sockvec;
324 root 1.1
325     extern sockvec clients;
326 root 1.24
327     #define for_all_clients(var) \
328     for (int _i = 0; _i < clients.size (); ++_i) \
329 root 1.52 statementvar (client *, var, clients [_i])
330 root 1.24
331 root 1.1 #endif
332