]> git.lizzy.rs Git - dragonfireclient.git/blob - src/connection.h
fixed crack animation timing in client
[dragonfireclient.git] / src / connection.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef CONNECTION_HEADER
21 #define CONNECTION_HEADER
22
23 #include <iostream>
24 #include <fstream>
25 #include "debug.h"
26 #include "common_irrlicht.h"
27 #include "socket.h"
28 #include "utility.h"
29 #include "exceptions.h"
30 #include "constants.h"
31
32 namespace con
33 {
34
35 /*
36         Exceptions
37 */
38 class NotFoundException : public BaseException
39 {
40 public:
41         NotFoundException(const char *s):
42                 BaseException(s)
43         {}
44 };
45
46 class PeerNotFoundException : public BaseException
47 {
48 public:
49         PeerNotFoundException(const char *s):
50                 BaseException(s)
51         {}
52 };
53
54 class ConnectionException : public BaseException
55 {
56 public:
57         ConnectionException(const char *s):
58                 BaseException(s)
59         {}
60 };
61
62 /*class ThrottlingException : public BaseException
63 {
64 public:
65         ThrottlingException(const char *s):
66                 BaseException(s)
67         {}
68 };*/
69
70 class InvalidIncomingDataException : public BaseException
71 {
72 public:
73         InvalidIncomingDataException(const char *s):
74                 BaseException(s)
75         {}
76 };
77
78 class InvalidOutgoingDataException : public BaseException
79 {
80 public:
81         InvalidOutgoingDataException(const char *s):
82                 BaseException(s)
83         {}
84 };
85
86 class NoIncomingDataException : public BaseException
87 {
88 public:
89         NoIncomingDataException(const char *s):
90                 BaseException(s)
91         {}
92 };
93
94 class ProcessedSilentlyException : public BaseException
95 {
96 public:
97         ProcessedSilentlyException(const char *s):
98                 BaseException(s)
99         {}
100 };
101
102 class GotSplitPacketException
103 {
104         SharedBuffer<u8> m_data;
105 public:
106         GotSplitPacketException(SharedBuffer<u8> data):
107                 m_data(data)
108         {}
109         SharedBuffer<u8> getData()
110         {
111                 return m_data;
112         }
113 };
114
115 inline u16 readPeerId(u8 *packetdata)
116 {
117         return readU16(&packetdata[4]);
118 }
119 inline u8 readChannel(u8 *packetdata)
120 {
121         return readU8(&packetdata[6]);
122 }
123
124 #define SEQNUM_MAX 65535
125 inline bool seqnum_higher(u16 higher, u16 lower)
126 {
127         if(lower > higher && lower - higher > SEQNUM_MAX/2){
128                 return true;
129         }
130         return (higher > lower);
131 }
132
133 struct BufferedPacket
134 {
135         BufferedPacket(u8 *a_data, u32 a_size):
136                 data(a_data, a_size), time(0.0), totaltime(0.0)
137         {}
138         BufferedPacket(u32 a_size):
139                 data(a_size), time(0.0), totaltime(0.0)
140         {}
141         SharedBuffer<u8> data; // Data of the packet, including headers
142         float time; // Seconds from buffering the packet or re-sending
143         float totaltime; // Seconds from buffering the packet
144         Address address; // Sender or destination
145 };
146
147 // This adds the base headers to the data and makes a packet out of it
148 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
149                 u32 protocol_id, u16 sender_peer_id, u8 channel);
150 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
151                 u32 protocol_id, u16 sender_peer_id, u8 channel);
152
153 // Add the TYPE_ORIGINAL header to the data
154 SharedBuffer<u8> makeOriginalPacket(
155                 SharedBuffer<u8> data);
156
157 // Split data in chunks and add TYPE_SPLIT headers to them
158 core::list<SharedBuffer<u8> > makeSplitPacket(
159                 SharedBuffer<u8> data,
160                 u32 chunksize_max,
161                 u16 seqnum);
162
163 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
164 // Increments split_seqnum if a split packet is made
165 core::list<SharedBuffer<u8> > makeAutoSplitPacket(
166                 SharedBuffer<u8> data,
167                 u32 chunksize_max,
168                 u16 &split_seqnum);
169
170 // Add the TYPE_RELIABLE header to the data
171 SharedBuffer<u8> makeReliablePacket(
172                 SharedBuffer<u8> data,
173                 u16 seqnum);
174
175 struct IncomingSplitPacket
176 {
177         IncomingSplitPacket()
178         {
179                 time = 0.0;
180                 reliable = false;
181         }
182         // Key is chunk number, value is data without headers
183         core::map<u16, SharedBuffer<u8> > chunks;
184         u32 chunk_count;
185         float time; // Seconds from adding
186         bool reliable; // If true, isn't deleted on timeout
187
188         bool allReceived()
189         {
190                 return (chunks.size() == chunk_count);
191         }
192 };
193
194 /*
195 === NOTES ===
196
197 A packet is sent through a channel to a peer with a basic header:
198 TODO: Should we have a receiver_peer_id also?
199         Header (7 bytes):
200         [0] u32 protocol_id
201         [4] u16 sender_peer_id
202         [6] u8 channel
203 sender_peer_id:
204         Unique to each peer.
205         value 0 is reserved for making new connections
206         value 1 is reserved for server
207 channel:
208         The lower the number, the higher the priority is.
209         Only channels 0, 1 and 2 exist.
210 */
211 #define BASE_HEADER_SIZE 7
212 #define PEER_ID_NEW 0
213 #define PEER_ID_SERVER 1
214 #define CHANNEL_COUNT 3
215 /*
216 Packet types:
217
218 CONTROL: This is a packet used by the protocol.
219 - When this is processed, nothing is handed to the user.
220         Header (2 byte):
221         [0] u8 type
222         [1] u8 controltype
223 controltype and data description:
224         CONTROLTYPE_ACK
225                 [2] u16 seqnum
226         CONTROLTYPE_SET_PEER_ID
227                 [2] u16 peer_id_new
228         CONTROLTYPE_PING
229         - This can be sent in a reliable packet to get a reply
230 */
231 #define TYPE_CONTROL 0
232 #define CONTROLTYPE_ACK 0
233 #define CONTROLTYPE_SET_PEER_ID 1
234 #define CONTROLTYPE_PING 2
235 /*
236 ORIGINAL: This is a plain packet with no control and no error
237 checking at all.
238 - When this is processed, it is directly handed to the user.
239         Header (1 byte):
240         [0] u8 type
241 */
242 #define TYPE_ORIGINAL 1
243 #define ORIGINAL_HEADER_SIZE 1
244 /*
245 SPLIT: These are sequences of packets forming one bigger piece of
246 data.
247 - When processed and all the packet_nums 0...packet_count-1 are
248   present (this should be buffered), the resulting data shall be
249   directly handed to the user.
250 - If the data fails to come up in a reasonable time, the buffer shall
251   be silently discarded.
252 - These can be sent as-is or atop of a RELIABLE packet stream.
253         Header (7 bytes):
254         [0] u8 type
255         [1] u16 seqnum
256         [3] u16 chunk_count
257         [5] u16 chunk_num
258 */
259 #define TYPE_SPLIT 2
260 /*
261 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
262 and they shall be delivered in the same order as sent. This is done
263 with a buffer in the receiving and transmitting end.
264 - When this is processed, the contents of each packet is recursively
265   processed as packets.
266         Header (3 bytes):
267         [0] u8 type
268         [1] u16 seqnum
269
270 */
271 #define TYPE_RELIABLE 3
272 #define RELIABLE_HEADER_SIZE 3
273 //#define SEQNUM_INITIAL 0x10
274 #define SEQNUM_INITIAL 65500
275
276 /*
277         A buffer which stores reliable packets and sorts them internally
278         for fast access to the smallest one.
279 */
280
281 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
282
283 class ReliablePacketBuffer
284 {
285 public:
286         
287         void print();
288         bool empty();
289         u32 size();
290         RPBSearchResult findPacket(u16 seqnum);
291         RPBSearchResult notFound();
292         u16 getFirstSeqnum();
293         BufferedPacket popFirst();
294         BufferedPacket popSeqnum(u16 seqnum);
295         void insert(BufferedPacket &p);
296         void incrementTimeouts(float dtime);
297         void resetTimedOuts(float timeout);
298         bool anyTotaltimeReached(float timeout);
299         core::list<BufferedPacket> getTimedOuts(float timeout);
300
301 private:
302         core::list<BufferedPacket> m_list;
303 };
304
305 /*
306         A buffer for reconstructing split packets
307 */
308
309 class IncomingSplitBuffer
310 {
311 public:
312         ~IncomingSplitBuffer();
313         /*
314                 This will throw a GotSplitPacketException when a full
315                 split packet is constructed.
316         */
317         void insert(BufferedPacket &p, bool reliable);
318         
319         void removeUnreliableTimedOuts(float dtime, float timeout);
320         
321 private:
322         // Key is seqnum
323         core::map<u16, IncomingSplitPacket*> m_buf;
324 };
325
326 class Connection;
327
328 struct Channel
329 {
330         Channel();
331         ~Channel();
332         /*
333                 Processes a packet with the basic header stripped out.
334                 Parameters:
335                         packetdata: Data in packet (with no base headers)
336                         con: The connection to which the channel is associated
337                              (used for sending back stuff (ACKs))
338                         peer_id: peer id of the sender of the packet in question
339                         channelnum: channel on which the packet was sent
340                         reliable: true if recursing into a reliable packet
341         */
342         SharedBuffer<u8> ProcessPacket(
343                         SharedBuffer<u8> packetdata,
344                         Connection *con,
345                         u16 peer_id,
346                         u8 channelnum,
347                         bool reliable=false);
348         
349         // Returns next data from a buffer if possible
350         // throws a NoIncomingDataException if no data is available
351         // If found, sets peer_id
352         SharedBuffer<u8> CheckIncomingBuffers(Connection *con,
353                         u16 &peer_id);
354
355         u16 next_outgoing_seqnum;
356         u16 next_incoming_seqnum;
357         u16 next_outgoing_split_seqnum;
358         
359         // This is for buffering the incoming packets that are coming in
360         // the wrong order
361         ReliablePacketBuffer incoming_reliables;
362         // This is for buffering the sent packets so that the sender can
363         // re-send them if no ACK is received
364         ReliablePacketBuffer outgoing_reliables;
365
366         IncomingSplitBuffer incoming_splits;
367 };
368
369 class Peer;
370
371 class PeerHandler
372 {
373 public:
374         PeerHandler()
375         {
376         }
377         virtual ~PeerHandler()
378         {
379         }
380         
381         /*
382                 This is called after the Peer has been inserted into the
383                 Connection's peer container.
384         */
385         virtual void peerAdded(Peer *peer) = 0;
386         /*
387                 This is called before the Peer has been removed from the
388                 Connection's peer container.
389         */
390         virtual void deletingPeer(Peer *peer, bool timeout) = 0;
391 };
392
393 class Peer
394 {
395 public:
396
397         Peer(u16 a_id, Address a_address);
398         virtual ~Peer();
399         
400         /*
401                 Calculates avg_rtt and resend_timeout.
402
403                 rtt=-1 only recalculates resend_timeout
404         */
405         void reportRTT(float rtt);
406
407         Channel channels[CHANNEL_COUNT];
408
409         // Address of the peer
410         Address address;
411         // Unique id of the peer
412         u16 id;
413         // Seconds from last receive
414         float timeout_counter;
415         // Ping timer
416         float ping_timer;
417         // This is changed dynamically
418         float resend_timeout;
419         // Updated when an ACK is received
420         float avg_rtt;
421         // This is set to true when the peer has actually sent something
422         // with the id we have given to it
423         bool has_sent_with_id;
424         
425 private:
426 };
427
428 class Connection
429 {
430 public:
431         Connection(
432                 u32 protocol_id,
433                 u32 max_packet_size,
434                 float timeout,
435                 PeerHandler *peerhandler
436         );
437         ~Connection();
438         void setTimeoutMs(int timeout){ m_socket.setTimeoutMs(timeout); }
439         // Start being a server
440         void Serve(unsigned short port);
441         // Connect to a server
442         void Connect(Address address);
443         bool Connected();
444
445         // Sets peer_id
446         SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
447
448         // The peer_id of sender is stored in peer_id
449         // Return value: I guess this always throws an exception or
450         //               actually gets data
451         u32 Receive(u16 &peer_id, u8 *data, u32 datasize);
452         
453         // These will automatically package the data as an original or split
454         void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
455         void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
456         // Send data as a packet; it will be wrapped in base header and
457         // optionally to a reliable packet.
458         void SendAsPacket(u16 peer_id, u8 channelnum,
459                         SharedBuffer<u8> data, bool reliable);
460         // Sends a raw packet
461         void RawSend(const BufferedPacket &packet);
462         
463         void RunTimeouts(float dtime);
464         // Can throw a PeerNotFoundException
465         Peer* GetPeer(u16 peer_id);
466         // returns NULL if failed
467         Peer* GetPeerNoEx(u16 peer_id);
468         core::list<Peer*> GetPeers();
469
470         void SetPeerID(u16 id){ m_peer_id = id; }
471         u16 GetPeerID(){ return m_peer_id; }
472         u32 GetProtocolID(){ return m_protocol_id; }
473
474         // For debug printing
475         void PrintInfo(std::ostream &out);
476         void PrintInfo();
477         u16 m_indentation;
478
479 private:
480         u32 m_protocol_id;
481         float m_timeout;
482         PeerHandler *m_peerhandler;
483         core::map<u16, Peer*> m_peers;
484         u16 m_peer_id;
485         //bool m_waiting_new_peer_id;
486         u32 m_max_packet_size;
487         UDPSocket m_socket;
488 };
489
490 } // namespace
491
492 #endif
493