// // Created by koncord on 07.01.17. // #include #include #include #include #include #include #include #include "Utils.hpp" using namespace std; unsigned int PingRakNetServer(const char *addr, unsigned short port) { RakNet::Packet *packet; bool done = false; int attempts = 0; RakNet::TimeMS time = PING_UNREACHABLE; RakNet::SocketDescriptor socketDescriptor {0, ""}; RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance(); peer->Startup(1,&socketDescriptor, 1); peer->Ping(addr, port, false); while (!done) { for (packet=peer->Receive(); packet; peer->DeallocatePacket(packet), packet=peer->Receive()) { if(packet->data[0] == ID_UNCONNECTED_PONG) { RakNet::BitStream bsIn(&packet->data[1], packet->length, false); bsIn.Read(time); time = RakNet::GetTimeMS() - time - 5; done = true; break; } } if (attempts >= 60) // wait 300 msec done = true; attempts++; RakSleep(5); } peer->Shutdown(0); RakNet::RakPeerInterface::DestroyInstance(peer); return time; } ServerExtendedData getExtendedData(const char *addr, unsigned short port) { ServerExtendedData data; RakNet::SocketDescriptor socketDescriptor = {0, ""}; RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance(); peer->Startup(1, &socketDescriptor, 1); stringstream sstr(TES3MP_VERSION); sstr << TES3MP_PROTO_VERSION; std::string msg = ""; if (peer->Connect(addr, port, sstr.str().c_str(), (int)(sstr.str().size()), 0, 0, 3, 500, 0) != RakNet::CONNECTION_ATTEMPT_STARTED) msg = "Connection attempt failed.\n"; bool queue = true; while (queue) { for (RakNet::Packet *packet = peer->Receive(); packet; peer->DeallocatePacket( packet), packet = peer->Receive()) { switch (packet->data[0]) { case ID_CONNECTION_ATTEMPT_FAILED: { msg = "Connection failed.\n" "Either the IP address is wrong or a firewall on either system is blocking\n" "UDP packets on the port you have chosen."; queue = false; break; } case ID_INVALID_PASSWORD: { msg = "Connection failed.\n" "The client or server is outdated.\n"; queue = false; break; } case ID_CONNECTION_REQUEST_ACCEPTED: { msg = "Connection accepted.\n"; queue = false; break; } case ID_DISCONNECTION_NOTIFICATION: throw runtime_error("ID_DISCONNECTION_NOTIFICATION.\n"); case ID_CONNECTION_BANNED: throw runtime_error("ID_CONNECTION_BANNED.\n"); case ID_CONNECTION_LOST: throw runtime_error("ID_CONNECTION_LOST.\n"); default: printf("Connection message with identifier %i has arrived in initialization.\n", packet->data[0]); } } } puts(msg.c_str()); { RakNet::BitStream bs; bs.Write((unsigned char) (ID_USER_PACKET_ENUM + 1)); peer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } RakNet::Packet *packet; bool done = false; while (!done) { for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive()) { if(packet->data[0] == (ID_USER_PACKET_ENUM+1)) { RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(1); size_t length = 0; bs.Read(length); for(int i = 0; i < length; i++) { RakNet::RakString str; bs.Read(str); data.players.push_back(str.C_String()); } bs.Read(length); for(int i = 0; i < length; i++) { RakNet::RakString str; bs.Read(str); data.plugins.push_back(str.C_String()); } done = true; } } } peer->Shutdown(0); RakSleep(10); RakNet::RakPeerInterface::DestroyInstance(peer); return data; }