Cosmetic changes, some minor refactoring.

This commit is contained in:
hiker 2015-10-22 18:40:52 +11:00
parent 1f4f2bce86
commit a102d97e3a
2 changed files with 203 additions and 169 deletions

View File

@ -38,31 +38,36 @@
#endif
// ----------------------------------------------------------------------------
ConnectToServer::ConnectToServer() :
Protocol(NULL, PROTOCOL_CONNECTION)
/** Quick join/
*/
ConnectToServer::ConnectToServer() : Protocol(NULL, PROTOCOL_CONNECTION)
{
m_server_id = 0;
m_server_id = 0;
m_host_id = 0;
m_quick_join = true;
m_state = NONE;
}
m_state = NONE;
} // ConnectToServer()
// ----------------------------------------------------------------------------
ConnectToServer::ConnectToServer(uint32_t server_id, uint32_t host_id) :
Protocol(NULL, PROTOCOL_CONNECTION)
/** Specify server to connect to.
* \param server_id Id of server to connect to.
* \param host_id Id of host.
*/
ConnectToServer::ConnectToServer(uint32_t server_id, uint32_t host_id)
: Protocol(NULL, PROTOCOL_CONNECTION)
{
m_server_id = server_id;
m_host_id = host_id;
m_server_id = server_id;
m_host_id = host_id;
m_quick_join = false;
m_state = NONE;
}
m_state = NONE;
} // ConnectToServer(server, host)
// ----------------------------------------------------------------------------
/** Destructor.
*/
ConnectToServer::~ConnectToServer()
{
}
} // ~ConnectToServer
// ----------------------------------------------------------------------------
@ -75,20 +80,18 @@ bool ConnectToServer::notifyEventAsynchronous(Event* event)
m_state = CONNECTED; // we received a message, we are connected
}
return true;
}
} // notifyEventAsynchronous
// ----------------------------------------------------------------------------
void ConnectToServer::setup()
{
Log::info("ConnectToServer", "SETUPP");
Log::info("ConnectToServer", "SETUP");
m_state = NONE;
m_server_address.clear();
m_current_protocol_id = 0;
}
} // setup
// ----------------------------------------------------------------------------
void ConnectToServer::asynchronousUpdate()
{
switch(m_state)
@ -96,154 +99,89 @@ void ConnectToServer::asynchronousUpdate()
case NONE:
{
Log::info("ConnectToServer", "Protocol starting");
m_current_protocol_id = m_listener->requestStart(new GetPublicAddress());
m_current_protocol_id =
m_listener->requestStart(new GetPublicAddress());
m_state = GETTING_SELF_ADDRESS;
break;
}
case GETTING_SELF_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id)
== PROTOCOL_STATE_TERMINATED) // now we know the public addr
if (m_listener->getProtocolState(m_current_protocol_id) ==
PROTOCOL_STATE_TERMINATED) // now we know the public addr
{
m_state = SHOWING_SELF_ADDRESS;
m_current_protocol_id = m_listener->requestStart(new ShowPublicAddress());
m_current_protocol_id =
m_listener->requestStart(new ShowPublicAddress());
Log::info("ConnectToServer", "Public address known");
/*
if (m_quick_join)
m_current_protocol_id = m_listener->requestStart(new QuickJoinProtocol(&m_server_address, &m_server_id));
else
m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_server_id, &m_server_address));*/
}
break;
case SHOWING_SELF_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id)
== PROTOCOL_STATE_TERMINATED) // now our public address is in the database
if (m_listener->getProtocolState(m_current_protocol_id) ==
PROTOCOL_STATE_TERMINATED)
{
// now our public address is in the database
Log::info("ConnectToServer", "Public address shown");
if (m_quick_join)
{
m_current_protocol_id = m_listener->requestStart(new QuickJoinProtocol(&m_server_address, &m_server_id));
m_current_protocol_id = m_listener->requestStart(
new QuickJoinProtocol(&m_server_address,
&m_server_id) );
m_state = REQUESTING_CONNECTION;
}
else
{
m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_host_id, &m_server_address));
m_current_protocol_id = m_listener->requestStart(
new GetPeerAddress(m_host_id,
&m_server_address) );
m_state = GETTING_SERVER_ADDRESS;
}
}
break;
case GETTING_SERVER_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id)
== PROTOCOL_STATE_TERMINATED) // we know the server address
if (m_listener->getProtocolState(m_current_protocol_id) ==
PROTOCOL_STATE_TERMINATED) // we know the server address
{
Log::info("ConnectToServer", "Server's address known");
// we're in the same lan (same public ip address) !!
if (m_server_address.getIP() ==
NetworkManager::getInstance()->getPublicAddress().getIP())
Log::info("ConnectToServer",
"Server appears to be in the same LAN.");
m_state = REQUESTING_CONNECTION;
m_current_protocol_id =
m_listener->requestStart(new RequestConnection(m_server_id));
}
break;
case REQUESTING_CONNECTION:
if (m_listener->getProtocolState(m_current_protocol_id)
== PROTOCOL_STATE_TERMINATED) // server knows we wanna connect
{
Log::info("ConnectToServer", "Connection request made");
if (m_server_address.getIP() == 0 ||
m_server_address.getPort() == 0 )
{ // server data not correct, hide address and stop
m_state = HIDING_ADDRESS;
Log::error("ConnectToServer", "Server address is %s",
m_server_address.toString().c_str());
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress());
return;
}
// we're in the same lan (same public ip address) !!
if (m_server_address.getIP() ==
NetworkManager::getInstance()->getPublicAddress().getIP())
{
// just send a broadcast packet, the client will know our ip address and will connect
STKHost* host = NetworkManager::getInstance()->getHost();
host->stopListening(); // stop the listening
TransportAddress sender;
TransportAddress broadcast_address;
broadcast_address.setIP(-1); // 255.255.255.255
broadcast_address.setPort(7321); // 0b10101100000101101101111111111111; // for test
char data2[] = "aloha_stk\0";
host->sendRawPacket((uint8_t*)(data2), 10, broadcast_address);
Log::info("ConnectToServer", "Waiting broadcast message.");
const uint8_t* received_data = host->receiveRawPacket(&sender); // get the sender
host->startListening(); // start listening again
const char data[] = "aloha_stk\0";
if (strcmp(data, (char*)(received_data)) == 0)
{
Log::info("ConnectToServer", "LAN Server found : %s",
sender.toString().c_str());
#ifndef WIN32
// just check if the ip is ours : if so, then just use localhost (127.0.0.1)
struct ifaddrs *ifap, *ifa;
struct sockaddr_in *sa;
getifaddrs (&ifap); // get the info
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr->sa_family==AF_INET)
{
sa = (struct sockaddr_in *) ifa->ifa_addr;
// This interface is ours
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
sender.setIP(0x7f000001); // 127.0.0.1
}
}
freeifaddrs(ifap);
#else
// Query the list of all IP addresses on the local host
// First call to GetIpAddrTable with 0 bytes buffer
// will return insufficient buffer error, and size
// will contain the number of bytes needed for all
// data. Repeat the process of querying the size
// using GetIpAddrTable in a while loop since it
// can happen that an interface comes online between
// the previous call to GetIpAddrTable and the next
// call.
MIB_IPADDRTABLE *table = NULL;
unsigned long size = 0;
int error = GetIpAddrTable(table, &size, 0);
// Also add a count to limit the while loop - in
// case that something strange is going on.
int count = 0;
while(error==ERROR_INSUFFICIENT_BUFFER && count < 10)
{
delete[] table; // deleting NULL is legal
table = (MIB_IPADDRTABLE*)new char[size];
error = GetIpAddrTable(table, &size, 0);
count ++;
} // while insufficient buffer
for(unsigned int i=0; i<table->dwNumEntries; i++)
{
unsigned int ip = ntohl(table->table[i].dwAddr);
if(sender.getIP() == ip) // this interface is ours
{
sender.setIP(0x7f000001); // 127.0.0.1
break;
}
}
delete[] table;
#endif
m_server_address.copy(sender);
m_state = CONNECTING;
}
Log::info("ConnectToServer",
"Server appears to be in the same LAN.");
}
m_state = REQUESTING_CONNECTION;
m_current_protocol_id =
m_listener->requestStart(
new RequestConnection(m_server_id));
}
break;
case REQUESTING_CONNECTION:
if (m_listener->getProtocolState(m_current_protocol_id) ==
PROTOCOL_STATE_TERMINATED)
{
// Server knows we want to connect
Log::info("ConnectToServer", "Connection request made");
if (m_server_address.getIP() == 0 ||
m_server_address.getPort() == 0 )
{
// server data not correct, hide address and stop
m_state = HIDING_ADDRESS;
Log::error("ConnectToServer", "Server address is %s",
m_server_address.toString().c_str());
m_current_protocol_id =
m_listener->requestStart(new HidePublicAddress());
return;
}
if (m_server_address.getIP() == NetworkManager::getInstance()
->getPublicAddress().getIP())
{
// we're in the same lan (same public ip address) !!
handleSameLAN();
}
else
{
m_state = CONNECTING;
m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_server_address, 2.0));
m_current_protocol_id = m_listener->requestStart(
new PingProtocol(m_server_address, 2.0));
}
}
break;
@ -262,20 +200,27 @@ void ConnectToServer::asynchronousUpdate()
case CONNECTED:
{
Log::info("ConnectToServer", "Connected");
m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress());
// Kill the ping protocol because we're connected
m_listener->requestTerminate(
m_listener->getProtocol(m_current_protocol_id));
m_current_protocol_id =
m_listener->requestStart(new HidePublicAddress());
ClientNetworkManager::getInstance()->setConnected(true);
m_state = HIDING_ADDRESS;
break;
}
case HIDING_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id)
== PROTOCOL_STATE_TERMINATED) // we have hidden our address
== PROTOCOL_STATE_TERMINATED) // we have hidden our address
{
Log::info("ConnectToServer", "Address hidden");
m_state = DONE;
if (ClientNetworkManager::getInstance()->isConnected()) // lobby room protocol if we're connected only
m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address));
// lobby room protocol if we're connected only
if (ClientNetworkManager::getInstance()->isConnected())
{
m_listener->requestStart(
new ClientLobbyRoomProtocol(m_server_address));
}
}
break;
case DONE:
@ -288,4 +233,88 @@ void ConnectToServer::asynchronousUpdate()
}
// ----------------------------------------------------------------------------
/** Called when the server is on the same LAN. It uses broadcast to
* find and conntect to the server.
*/
void ConnectToServer::handleSameLAN()
{
// just send a broadcast packet, the client will know our
// ip address and will connect
STKHost* host = NetworkManager::getInstance()->getHost();
host->stopListening(); // stop the listening
TransportAddress broadcast_address;
broadcast_address.setIP(-1); // 255.255.255.255
broadcast_address.setPort(7321);
char data2[] = "aloha_stk\0";
host->sendRawPacket((uint8_t*)(data2), 10, broadcast_address);
Log::info("ConnectToServer", "Waiting broadcast message.");
TransportAddress sender;
// get the sender
const uint8_t* received_data = host->receiveRawPacket(&sender);
host->startListening(); // start listening again
const char data[] = "aloha_stk\0";
if (strcmp(data, (char*)(received_data)) == 0)
{
Log::info("ConnectToServer", "LAN Server found : %s",
sender.toString().c_str());
#ifndef WIN32
// just check if the ip is ours : if so,
// then just use localhost (127.0.0.1)
struct ifaddrs *ifap, *ifa;
struct sockaddr_in *sa;
getifaddrs(&ifap); // get the info
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr->sa_family == AF_INET)
{
sa = (struct sockaddr_in *) ifa->ifa_addr;
// This interface is ours
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
sender.setIP(0x7f000001); // 127.0.0.1
}
}
freeifaddrs(ifap);
#else
// Query the list of all IP addresses on the local host
// First call to GetIpAddrTable with 0 bytes buffer
// will return insufficient buffer error, and size
// will contain the number of bytes needed for all
// data. Repeat the process of querying the size
// using GetIpAddrTable in a while loop since it
// can happen that an interface comes online between
// the previous call to GetIpAddrTable and the next
// call.
MIB_IPADDRTABLE *table = NULL;
unsigned long size = 0;
int error = GetIpAddrTable(table, &size, 0);
// Also add a count to limit the while loop - in
// case that something strange is going on.
int count = 0;
while (error == ERROR_INSUFFICIENT_BUFFER && count < 10)
{
delete[] table; // deleting NULL is legal
table = (MIB_IPADDRTABLE*)new char[size];
error = GetIpAddrTable(table, &size, 0);
count++;
} // while insufficient buffer
for (unsigned int i = 0; i < table->dwNumEntries; i++)
{
unsigned int ip = ntohl(table->table[i].dwAddr);
if (sender.getIP() == ip) // this interface is ours
{
sender.setIP(0x7f000001); // 127.0.0.1
break;
}
}
delete[] table;
#endif
m_server_address.copy(sender);
m_state = CONNECTING;
}
} // handleSameLAN

View File

@ -21,41 +21,46 @@
#include "network/protocol.hpp"
#include "network/types.hpp"
#include "utils/cpp2011.hpp"
#include <string>
class ConnectToServer : public Protocol, public CallbackObject
{
public:
ConnectToServer(); //!< Quick join
ConnectToServer(uint32_t server_id, uint32_t host_id); //!< Specify server id
virtual ~ConnectToServer();
private:
TransportAddress m_server_address;
uint32_t m_server_id;
uint32_t m_host_id;
uint32_t m_current_protocol_id;
bool m_quick_join;
virtual bool notifyEventAsynchronous(Event* event);
virtual void setup();
virtual void update() {}
virtual void asynchronousUpdate();
enum State
{
NONE,
GETTING_SELF_ADDRESS,
SHOWING_SELF_ADDRESS,
GETTING_SERVER_ADDRESS,
REQUESTING_CONNECTION,
CONNECTING,
CONNECTED,
HIDING_ADDRESS,
DONE,
EXITING
};
/** State for finite state machine. */
State m_state;
protected:
TransportAddress m_server_address;
uint32_t m_server_id;
uint32_t m_host_id;
uint32_t m_current_protocol_id;
bool m_quick_join;
void handleSameLAN();
enum STATE
{
NONE,
GETTING_SELF_ADDRESS,
SHOWING_SELF_ADDRESS,
GETTING_SERVER_ADDRESS,
REQUESTING_CONNECTION,
CONNECTING,
CONNECTED,
HIDING_ADDRESS,
DONE,
EXITING
};
STATE m_state;
};
public:
ConnectToServer();
ConnectToServer(uint32_t server_id, uint32_t host_id);
virtual ~ConnectToServer();
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
virtual void setup() OVERRIDE;
virtual void asynchronousUpdate();
virtual void update() OVERRIDE {}
}; // class ConnectToServer
#endif // CONNECT_TO_SERVER_HPP