1 /*
2  * common/CommonNetwork.cpp
3  *
4  * This file is part of Leges Motus, a networked, 2D shooter set in zero gravity.
5  *
6  * Copyright 2009-2010 Andrew Ayer, Nathan Partlan, Jeffrey Pfau
7  *
8  * Leges Motus is free and open source software.  You may redistribute it and/or
9  * modify it under the terms of version 2, or (at your option) version 3, of the
10  * GNU General Public License (GPL), as published by the Free Software Foundation.
11  *
12  * Leges Motus is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14  * PARTICULAR PURPOSE.  See the full text of the GNU General Public License for
15  * further detail.
16  *
17  * For a full copy of the GNU General Public License, please see the COPYING file
18  * in the root of the source code tree.  You may also retrieve a copy from
19  * <http://www.gnu.org/licenses/gpl-2.0.txt>, or request a copy by writing to the
20  * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  * 02111-1307  USA
22  *
23  */
24 
25 #include "CommonNetwork.hpp"
26 #include "UDPPacket.hpp"
27 #include "IPAddress.hpp"
28 #include "PacketReader.hpp"
29 #include "PacketWriter.hpp"
30 #include "network.hpp"
31 #include <stdint.h>
32 #include <stdlib.h>
33 
34 using namespace LM;
35 using namespace std;
36 
Peer()37 CommonNetwork::Peer::Peer ()
38 {
39 	next_sequence_no = 1L;
40 }
41 
init(uint32_t arg_connection_id,uint64_t next_send_sequence_no,uint64_t next_receive_sequence_no)42 void	CommonNetwork::Peer::init (uint32_t arg_connection_id, uint64_t next_send_sequence_no, uint64_t next_receive_sequence_no)
43 {
44 	connection_id = arg_connection_id;
45 	next_sequence_no = next_send_sequence_no;
46 	packet_queue.init(next_receive_sequence_no);
47 }
48 
send_raw_packet(const UDPPacket & raw_packet)49 void	CommonNetwork::send_raw_packet(const UDPPacket& raw_packet) {
50 /*
51 	static UDPPacket*	buffered_packet = NULL;
52 	static long		packet_count = 0;
53 
54 	++packet_count;
55 
56 	if (packet_count > 30 && rand() % 3 == 0) {
57 		return;
58 	}
59 
60 	if (packet_count > 30) {
61 		if (buffered_packet) {
62 			m_socket.send(raw_packet);
63 			m_socket.send(*buffered_packet);
64 			delete buffered_packet;
65 			buffered_packet = NULL;
66 		} else if (rand() % 3 == 0) {
67 			buffered_packet = new UDPPacket(raw_packet);
68 		}
69 	} else {
70 		m_socket.send(raw_packet);
71 	}
72 	*/
73 
74 	m_socket.send(raw_packet);
75 	//m_socket.send(raw_packet);
76 	//m_socket.send(raw_packet);
77 }
78 
receive_raw_packet(UDPPacket & raw_packet)79 bool	CommonNetwork::receive_raw_packet(UDPPacket& raw_packet) {
80 	return m_socket.has_packets() && m_socket.recv(raw_packet);
81 }
82 
send_ack(const IPAddress & peer,const PacketReader & packet_to_ack)83 void	CommonNetwork::send_ack(const IPAddress& peer, const PacketReader& packet_to_ack) {
84 	PacketWriter		ack_packet(ACK_PACKET);
85 	ack_packet << packet_to_ack.packet_type() << packet_to_ack.sequence_no();
86 	send_packet(peer, ack_packet);
87 }
88 
process_ack(const IPAddress & peer,PacketReader & ack_packet)89 void	CommonNetwork::process_ack(const IPAddress& peer, PacketReader& ack_packet) {
90 	uint32_t	packet_type;
91 	uint64_t	sequence_no;
92 	ack_packet >> packet_type >> sequence_no;
93 
94 	m_ack_manager.ack(peer, sequence_no);
95 }
96 
send_packet(const IPAddress & dest,const PacketWriter & packet)97 void	CommonNetwork::send_packet(const IPAddress& dest, const PacketWriter& packet) {
98 	send_packet(dest, packet.get_header(), packet.packet_data());
99 }
100 
send_packet(const IPAddress & dest,const PacketHeader & packet_header,const std::string & packet_data)101 void	CommonNetwork::send_packet(const IPAddress& dest, const PacketHeader& packet_header, const std::string& packet_data) {
102 	UDPPacket	raw_packet(MAX_PACKET_LENGTH);
103 	raw_packet.set_address(dest);
104 	raw_packet.fill(packet_header.make_string());
105 	raw_packet.append(packet_data);
106 	send_raw_packet(raw_packet);
107 }
108 
resend_acks()109 void	CommonNetwork::resend_acks() {
110 	m_ack_manager.resend(*this);
111 }
112 
113