1 /*
2  * serverscanner/ServerScannerNetwork.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 <string>
26 #include "ServerScannerNetwork.hpp"
27 #include "ServerScanner.hpp"
28 #include "common/network.hpp"
29 #include "common/PacketWriter.hpp"
30 #include "common/PacketReader.hpp"
31 #include "common/PacketHeader.hpp"
32 #include "common/UDPPacket.hpp"
33 #include "common/UDPSocket.hpp"
34 #include "common/IPAddress.hpp"
35 #include "common/timer.hpp"
36 #include <iostream>
37 
38 using namespace LM;
39 using namespace std;
40 
41 uint32_t	ServerScannerNetwork::next_connection_id = 1;
42 
ServerScannerNetwork(ServerScanner & controller)43 ServerScannerNetwork::ServerScannerNetwork(ServerScanner& controller) : m_controller(controller) {
44 	m_is_connected = false;
45 	m_last_packet_time = 0;
46 }
47 
connect(const char * hostname,unsigned int portno)48 bool	ServerScannerNetwork::connect(const char* hostname, unsigned int portno) {
49 	disconnect();
50 
51 	if (!resolve_hostname(m_server_address, hostname, portno)) {
52 		return false;
53 	}
54 
55 	m_ack_manager.clear();
56 	m_is_connected = true;
57 	m_last_packet_time = 0;
58 	return true;
59 }
60 
connect(const IPAddress & address)61 bool	ServerScannerNetwork::connect(const IPAddress& address) {
62 	disconnect();
63 	m_ack_manager.clear();
64 	m_server_address = address;
65 	m_is_connected = true;
66 	m_last_packet_time = 0;
67 	return true;
68 }
69 
disconnect()70 void	ServerScannerNetwork::disconnect() {
71 	m_is_connected = false;
72 	m_server_peer.init(next_connection_id++);
73 	m_server_peer.packet_queue.set_max_size(1024);
74 }
75 
76 
send_reliable_packet(const PacketWriter & packet)77 void	ServerScannerNetwork::send_reliable_packet(const PacketWriter& packet) {
78 	if (!is_connected()) {
79 		return;
80 	}
81 
82 	PacketHeader	header(packet.packet_type(), m_server_peer.next_sequence_no++, m_server_peer.connection_id);
83 	send_packet_to(m_server_address, header, packet.packet_data());
84 	m_ack_manager.add_packet(m_server_address, header, packet.packet_data());
85 }
86 
87 
send_packet(const PacketHeader & packet_header,const std::string & packet_data)88 void	ServerScannerNetwork::send_packet(const PacketHeader& packet_header, const std::string& packet_data) {
89 	if (is_connected()) {
90 		send_packet_to(m_server_address, packet_header, packet_data);
91 	}
92 }
93 
94 
broadcast_packet(unsigned int portno,const PacketWriter & packet)95 void	ServerScannerNetwork::broadcast_packet(unsigned int portno, const PacketWriter& packet) {
96 	send_packet_to(IPAddress(htonl(INADDR_BROADCAST), htons(portno)), packet);
97 }
98 
receive_packets(uint32_t timeout)99 bool	ServerScannerNetwork::receive_packets(uint32_t timeout) {
100 	UDPPacket	raw_packet(MAX_PACKET_LENGTH);
101 	// Block until packets are received, timeout has elapsed, or a signal has been received.
102 	bool		has_packets = m_socket.has_packets(timeout);
103 	// Keep receiving packets for as long as we can.
104 	while (receive_raw_packet(raw_packet)) {
105 		process_unbound_packet(raw_packet);
106 	}
107 
108 	return has_packets;
109 }
110 
process_unbound_packet(const UDPPacket & raw_packet)111 void	ServerScannerNetwork::process_unbound_packet(const UDPPacket& raw_packet) {
112 	PacketReader	reader(raw_packet);
113 
114 	switch (reader.packet_type()) {
115 	case INFO_PACKET:
116 		m_controller.server_info(raw_packet.get_address(), reader);
117 		break;
118 	case UPGRADE_AVAILABLE_PACKET:
119 		m_controller.upgrade_available(raw_packet.get_address(), reader);
120 		break;
121 	case HOLE_PUNCH_PACKET:
122 		m_controller.hole_punch_packet(raw_packet.get_address(), reader);
123 		break;
124 	}
125 }
126 
get_last_packet_time()127 uint64_t ServerScannerNetwork::get_last_packet_time() {
128 	return m_last_packet_time;
129 }
130 
131