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 #endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Quick join/
ConnectToServer::ConnectToServer() : */
Protocol(NULL, PROTOCOL_CONNECTION) ConnectToServer::ConnectToServer() : Protocol(NULL, PROTOCOL_CONNECTION)
{ {
m_server_id = 0; m_server_id = 0;
m_host_id = 0;
m_quick_join = true; m_quick_join = true;
m_state = NONE; m_state = NONE;
} } // ConnectToServer()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Specify server to connect to.
ConnectToServer::ConnectToServer(uint32_t server_id, uint32_t host_id) : * \param server_id Id of server to connect to.
Protocol(NULL, PROTOCOL_CONNECTION) * \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_server_id = server_id;
m_host_id = host_id; m_host_id = host_id;
m_quick_join = false; m_quick_join = false;
m_state = NONE; m_state = NONE;
} } // ConnectToServer(server, host)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Destructor.
*/
ConnectToServer::~ConnectToServer() ConnectToServer::~ConnectToServer()
{ {
} } // ~ConnectToServer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -75,20 +80,18 @@ bool ConnectToServer::notifyEventAsynchronous(Event* event)
m_state = CONNECTED; // we received a message, we are connected m_state = CONNECTED; // we received a message, we are connected
} }
return true; return true;
} } // notifyEventAsynchronous
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ConnectToServer::setup() void ConnectToServer::setup()
{ {
Log::info("ConnectToServer", "SETUPP"); Log::info("ConnectToServer", "SETUP");
m_state = NONE; m_state = NONE;
m_server_address.clear(); m_server_address.clear();
m_current_protocol_id = 0; m_current_protocol_id = 0;
} } // setup
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ConnectToServer::asynchronousUpdate() void ConnectToServer::asynchronousUpdate()
{ {
switch(m_state) switch(m_state)
@ -96,154 +99,89 @@ void ConnectToServer::asynchronousUpdate()
case NONE: case NONE:
{ {
Log::info("ConnectToServer", "Protocol starting"); 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; m_state = GETTING_SELF_ADDRESS;
break; break;
} }
case GETTING_SELF_ADDRESS: case GETTING_SELF_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id) if (m_listener->getProtocolState(m_current_protocol_id) ==
== PROTOCOL_STATE_TERMINATED) // now we know the public addr PROTOCOL_STATE_TERMINATED) // now we know the public addr
{ {
m_state = SHOWING_SELF_ADDRESS; 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"); 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; break;
case SHOWING_SELF_ADDRESS: case SHOWING_SELF_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id) if (m_listener->getProtocolState(m_current_protocol_id) ==
== PROTOCOL_STATE_TERMINATED) // now our public address is in the database PROTOCOL_STATE_TERMINATED)
{ {
// now our public address is in the database
Log::info("ConnectToServer", "Public address shown"); Log::info("ConnectToServer", "Public address shown");
if (m_quick_join) 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; m_state = REQUESTING_CONNECTION;
} }
else 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; m_state = GETTING_SERVER_ADDRESS;
} }
} }
break; break;
case GETTING_SERVER_ADDRESS: case GETTING_SERVER_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id) if (m_listener->getProtocolState(m_current_protocol_id) ==
== PROTOCOL_STATE_TERMINATED) // we know the server address PROTOCOL_STATE_TERMINATED) // we know the server address
{ {
Log::info("ConnectToServer", "Server's address known"); Log::info("ConnectToServer", "Server's address known");
// we're in the same lan (same public ip address) !! // 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() == if (m_server_address.getIP() ==
NetworkManager::getInstance()->getPublicAddress().getIP()) NetworkManager::getInstance()->getPublicAddress().getIP())
{ {
// just send a broadcast packet, the client will know our ip address and will connect Log::info("ConnectToServer",
STKHost* host = NetworkManager::getInstance()->getHost(); "Server appears to be in the same LAN.");
host->stopListening(); // stop the listening }
TransportAddress sender; m_state = REQUESTING_CONNECTION;
m_current_protocol_id =
TransportAddress broadcast_address; m_listener->requestStart(
broadcast_address.setIP(-1); // 255.255.255.255 new RequestConnection(m_server_id));
broadcast_address.setPort(7321); // 0b10101100000101101101111111111111; // for test }
char data2[] = "aloha_stk\0"; break;
host->sendRawPacket((uint8_t*)(data2), 10, broadcast_address); case REQUESTING_CONNECTION:
if (m_listener->getProtocolState(m_current_protocol_id) ==
Log::info("ConnectToServer", "Waiting broadcast message."); PROTOCOL_STATE_TERMINATED)
const uint8_t* received_data = host->receiveRawPacket(&sender); // get the sender {
// Server knows we want to connect
host->startListening(); // start listening again Log::info("ConnectToServer", "Connection request made");
const char data[] = "aloha_stk\0"; if (m_server_address.getIP() == 0 ||
if (strcmp(data, (char*)(received_data)) == 0) m_server_address.getPort() == 0 )
{ {
Log::info("ConnectToServer", "LAN Server found : %s", // server data not correct, hide address and stop
sender.toString().c_str()); m_state = HIDING_ADDRESS;
#ifndef WIN32 Log::error("ConnectToServer", "Server address is %s",
// just check if the ip is ours : if so, then just use localhost (127.0.0.1) m_server_address.toString().c_str());
struct ifaddrs *ifap, *ifa; m_current_protocol_id =
struct sockaddr_in *sa; m_listener->requestStart(new HidePublicAddress());
getifaddrs (&ifap); // get the info return;
for (ifa = ifap; ifa; ifa = ifa->ifa_next) }
{ if (m_server_address.getIP() == NetworkManager::getInstance()
if (ifa->ifa_addr->sa_family==AF_INET) ->getPublicAddress().getIP())
{ {
sa = (struct sockaddr_in *) ifa->ifa_addr; // we're in the same lan (same public ip address) !!
handleSameLAN();
// 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;
}
} }
else else
{ {
m_state = CONNECTING; 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; break;
@ -262,20 +200,27 @@ void ConnectToServer::asynchronousUpdate()
case CONNECTED: case CONNECTED:
{ {
Log::info("ConnectToServer", "Connected"); Log::info("ConnectToServer", "Connected");
m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected // Kill the ping protocol because we're connected
m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); m_listener->requestTerminate(
m_listener->getProtocol(m_current_protocol_id));
m_current_protocol_id =
m_listener->requestStart(new HidePublicAddress());
ClientNetworkManager::getInstance()->setConnected(true); ClientNetworkManager::getInstance()->setConnected(true);
m_state = HIDING_ADDRESS; m_state = HIDING_ADDRESS;
break; break;
} }
case HIDING_ADDRESS: case HIDING_ADDRESS:
if (m_listener->getProtocolState(m_current_protocol_id) 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"); Log::info("ConnectToServer", "Address hidden");
m_state = DONE; m_state = DONE;
if (ClientNetworkManager::getInstance()->isConnected()) // lobby room protocol if we're connected only // lobby room protocol if we're connected only
m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address)); if (ClientNetworkManager::getInstance()->isConnected())
{
m_listener->requestStart(
new ClientLobbyRoomProtocol(m_server_address));
}
} }
break; break;
case DONE: 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/protocol.hpp"
#include "network/types.hpp" #include "network/types.hpp"
#include "utils/cpp2011.hpp"
#include <string> #include <string>
class ConnectToServer : public Protocol, public CallbackObject class ConnectToServer : public Protocol, public CallbackObject
{ {
public: private:
ConnectToServer(); //!< Quick join TransportAddress m_server_address;
ConnectToServer(uint32_t server_id, uint32_t host_id); //!< Specify server id uint32_t m_server_id;
virtual ~ConnectToServer(); uint32_t m_host_id;
uint32_t m_current_protocol_id;
bool m_quick_join;
virtual bool notifyEventAsynchronous(Event* event); enum State
virtual void setup(); {
virtual void update() {} NONE,
virtual void asynchronousUpdate(); 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: void handleSameLAN();
TransportAddress m_server_address;
uint32_t m_server_id;
uint32_t m_host_id;
uint32_t m_current_protocol_id;
bool m_quick_join;
enum STATE public:
{ ConnectToServer();
NONE, ConnectToServer(uint32_t server_id, uint32_t host_id);
GETTING_SELF_ADDRESS, virtual ~ConnectToServer();
SHOWING_SELF_ADDRESS,
GETTING_SERVER_ADDRESS, virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
REQUESTING_CONNECTION, virtual void setup() OVERRIDE;
CONNECTING, virtual void asynchronousUpdate();
CONNECTED, virtual void update() OVERRIDE {}
HIDING_ADDRESS,
DONE, }; // class ConnectToServer
EXITING
};
STATE m_state;
};
#endif // CONNECT_TO_SERVER_HPP #endif // CONNECT_TO_SERVER_HPP