void CRakMasterServer::RegisterServer(RakNet::SystemAddress& _rServerAddress, RakNet::RakNetGUID& _rServerGuid, uchar* _ucpData, uint _uiLength) { std::map<uint64, TServerDetails*>::iterator Entry = m_mRegisteredServers.find(_rServerGuid.g); if (Entry == m_mRegisteredServers.end()) { TServerDetails* tpServerDetails = new TServerDetails(); char sServerIp[256]; _rServerAddress.ToString_Old(false, sServerIp); tpServerDetails->tAddress = _rServerAddress; tpServerDetails->tGuid = _rServerGuid; tpServerDetails->fUnregisterTimer = s_kfRegistrationTimeout; m_mRegisteredServers.insert( std::pair<uint64, TServerDetails*>(_rServerGuid.g, tpServerDetails) ); LOG_MESSAGE("Registered Server. IP(%s) GUID(%llu)", _rServerAddress.ToString(), _rServerGuid.g); } else { Entry->second->fUnregisterTimer = s_kfRegistrationTimeout; LOG_MESSAGE("Re-registered Server. IP(%s) GUID(%llu)", _rServerAddress.ToString(), _rServerGuid.g); } }
void PrintStatus( void ) { // enumerate local addresses size_t numAddresses = peer->GetNumberOfAddresses(); if ( numAddresses ) { console.Print( PrintLevel::Normal, "Network primed on:\n" ); for ( size_t i = 0u; i < numAddresses; i++ ) { Indent indent( 1u ); console.Print( PrintLevel::Normal, "%i. %s\n", i + 1, peer->GetLocalIP( i ) ); } } else { console.Print( PrintLevel::Normal, "Network primed on %s\n", peer->GetMyBoundAddress().ToString() ); } console.Print( PrintLevel::Normal, "GUID: %" PRIX64 "\n", myGUID ); // get a list of remote connections uint16_t numRemoteSystems; peer->GetConnectionList( nullptr, &numRemoteSystems ); RakNet::SystemAddress *remoteSystems = new RakNet::SystemAddress[numRemoteSystems]; peer->GetConnectionList( remoteSystems, &numRemoteSystems ); console.Print( PrintLevel::Normal, "%i connections (max: %i)\n", numRemoteSystems, peer->GetMaximumIncomingConnections() ); if ( numRemoteSystems ) { console.Print( PrintLevel::Normal, "Listing active connections...\n" ); for ( size_t i = 0u; i < numRemoteSystems; i++ ) { RakNet::SystemAddress *sa = &remoteSystems[i]; Indent indent( 1u ); std::string type; if ( sa->IsLANAddress() ) { type = " LAN"; } else if ( sa->IsLoopback() ) { type = "LOOP"; } else { type = "INET"; } console.Print( PrintLevel::Normal, "%s: %s - %s\n", type.c_str(), sa->ToString(), connectionStateMessages[peer->GetConnectionState( *sa )] ); } } delete[] remoteSystems; }
bool Network::is_in_same_network(std::string const& other) const { RakNet::SystemAddress o; RakNet::SystemAddress self; if (o.FromString(other.c_str()) && self.FromString(external_id_.c_str())) { if (o.EqualsExcludingPort(self)) { return true; } } return false; }
// Returning false prevents the proxy from forwarding current packet to the client bool CProxy::HandleLoginSrvPacket(RakNet::Packet* pPacket, RakNet::SystemAddress& clientAddr, RakNet::BitStream& inStr, uchar opCode) { uint off = inStr.GetReadOffset(); switch (opCode) { case Opcodes::OP_LOGIN: bool bLoggedIn = false; inStr.Read(bLoggedIn); if (bLoggedIn) { ff::fmt(pan::debug, "({0}) Player successfully logged in.", clientAddr.ToString(false)); // Do the switch to Area server here } break; } inStr.SetReadOffset(off); return true; }
bool NetworkEngine::canConnected(RakNet::SystemAddress id) { RakNet::SystemAddress connecteds[MAX_PLAYERS]; unsigned short size = MAX_PLAYERS; //unsigned short pos = peer->NumberOfConnections(); //peer->GetConnectionList(connecteds,&pos); peer->GetConnectionList((RakNet::SystemAddress*) &connecteds,&size); if(disconnecteds.size() > 0) { std::vector<RakNet::SystemAddress>::iterator it = disconnecteds.begin(); do { if(id.EqualsExcludingPort(*it)) { disconnecteds.erase(it); return true; } it++; }while(it != disconnecteds.end()); } for(int i=0;i<MAX_PLAYERS;i++) { if(connecteds[i].EqualsExcludingPort(id)) { return false; } } return false; }
void Connector::connect( RakNet::SystemAddress server ){ if (raknetInterface == nullptr){ LOG("Client is not started!"); return; } char * ip = new char[64]; // must be new char[]! Not char ip[], BAD_ACCESS!! for(int i=0; i<64; i++){ ip[i] = 0; } server.ToString(false, ip); int result = raknetInterface->Connect(ip, server.GetPort(), RAKNET_PASSWORD, (int)strlen(RAKNET_PASSWORD)); LOG("[Connector] Connecting to %s", ip); if(result == RakNet::CONNECTION_ATTEMPT_STARTED) { LOG("[Connector] Connecting to %s started.", ip); } else if (result == RakNet::INVALID_PARAMETER) { LOG("[Connector] INVALID_PARAMETER"); } else if (result == RakNet::CANNOT_RESOLVE_DOMAIN_NAME) { LOG("[Connector] CANNOT_RESOLVE_DOMAIN_NAME"); } else if (result == RakNet::ALREADY_CONNECTED_TO_ENDPOINT) { LOG("[Connector] ALREADY_CONNECTED_TO_ENDPOINT"); } else if (result == RakNet::CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS) { LOG("[Connector] CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS"); } else if (result == RakNet::SECURITY_INITIALIZATION_FAILED) { LOG("[Connector] SECURITY_INITIALIZATION_FAILED"); } else{ LOG("[Connector] connecting atempt failed for unknown reason!!!"); } delete [] ip; }
void NetworkEngine::sendMessagePlayerReconnected(RakNet::SystemAddress systemAddress) { //Envia un ID_SERVER_MESSAGE con un RakNet::String; RakNet::BitStream bitStream; RakNet::RakString string("Player %s has reconnected to the game\n", systemAddress.ToString()); bitStream.Write((unsigned char)ID_SERVER_STRING_MESSAGE); bitStream.Write(string); peer->Send(&bitStream, HIGH_PRIORITY, RELIABLE, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); }
void ClientChatNetPackageSender::sendData( const char* data, int lenght ) { const NetworkAddress& networkAddress(getPeer()->getNetworkAddress()); RakNet::SystemAddress target; target.FromStringExplicitPort(networkAddress.getServerIp(),networkAddress.getServerPort()); // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order // We arbitrarily pick 0 for the ordering stream // target.FromStringExplicitPort created the address to send the data to // false means send the message to the given target address RakNet::RakPeerInterface* rakNetPeer(getPeer()->accessRakNetPeer()); // note: better check if the peer is connected in the first place if(rakNetPeer != nullptr) { rakNetPeer->Send(data, lenght, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false); } }
///加条发送的消息 void SimulateClientMainFrame::addReceiveMessage(const std::string& message,const RakNet::SystemAddress& Address) { wxString tem; tem+=Address.ToString(); tem+=": "; tem+=message; tem+="\n"; m_receiveText->AppendText(tem); }
//------------------------------------------------------------------------------------ void PlayerManager::processDatabasePlayer(NetPack* pPack) { ///把数据转发给客户端 Tag_PlayerCollect* players=static_cast<Tag_PlayerCollect*>(pPack->getData()); if(players->m_Count==0)///表示这个帐号还没有新建角色 { }else ///把所有角色发给客户端 { } RakNet::SystemAddress address; address.SetBinaryAddress(players->m_ip); NetWorkServer::getSingleton().send(GM_REQUEST_PLAYERS,(const char*)pPack->getData(),pPack->getDataLength(),address); return ; }
void CProxy::OnClosedConnection(const RakNet::SystemAddress& systemAddress, RakNet::RakNetGUID rakNetGUID, RakNet::PI2_LostConnectionReason lostConnectionReason) { ff::fmt(pan::notice, "({0}) Closed connection", systemAddress.ToString(false)); s_clientInfos* pInfos = m_mapClientAddr[systemAddress]; m_mapClientAddr.erase(systemAddress); std::map<uint, s_clientInfos*>::iterator it = m_mapClientId.find(pInfos->m_uID); if (it != m_mapClientId.end()) m_mapClientId.erase(it); }
void Network_module::run() { print_config(); using namespace RakNet; RakNet::RakPeerInterface* l_rakpeer = RakNet::RakPeerInterface::GetInstance(); int l_addr_count = l_rakpeer->GetNumberOfAddresses(); NET_MOD_INFO("获取到本机IP数量%d个", l_addr_count); for (int i = 0; i < l_addr_count; i++) { RakNet::SystemAddress addr = l_rakpeer->GetLocalIP(i); NET_MOD_INFO("第%d个IP地址为:%s", i + 1, addr.ToString(false)); } RakNet::SocketDescriptor l_socket_descriptor; l_socket_descriptor.port = m_local_port; if (l_rakpeer->Startup(m_max_connection, &l_socket_descriptor, 1) != RakNet::RAKNET_STARTED) { NET_MOD_ERROR("启动网络引擎失败"); RakNet::RakPeerInterface::DestroyInstance(l_rakpeer); return; } l_rakpeer->SetMaximumIncomingConnections(m_max_income_connection); NET_MOD_INFO("启动网络引擎成功,监控地址为%s", l_rakpeer->GetMyBoundAddress().ToString(false)); NET_MOD_INFO("开始载入打孔插件"); m_punch_proxy = new NatPunchProxy; m_punch_proxy->init_proxy(l_rakpeer); start_network_loop(l_rakpeer); }
// Triggered when a new client connect to the proxy. void CProxy::OnNewConnection(const RakNet::SystemAddress& systemAddress, RakNet::RakNetGUID rakNetGUID, bool isIncoming) { ff::fmt(pan::notice, "({0}) New connection", systemAddress.ToString(false)); // Setup client infos s_clientInfos* pInfos = new s_clientInfos(); pInfos->m_clientAddr = systemAddress; pInfos->m_pMainSrv = m_pLoginSrvInterface; pInfos->m_rakGUID = rakNetGUID; pInfos->m_uID = 0; pInfos->m_sendFunc = FastDelegate<RakNet::PluginReceiveResult(RakNet::Packet*, s_clientInfos*)>(this, &CProxy::OnLoginClientReceive); // For now we can only identify this client by his address. m_mapClientAddr[systemAddress] = pInfos; }
int main(int argc, char **argv) { const char *DEFAULT_SERVER_ADDRESS="test.dnsalias.net"; const unsigned short DEFAULT_SERVER_PORT=60000; const char *serverAddress; unsigned short serverPort; #ifndef _DEBUG // Only use DEFAULT_SERVER_ADDRESS for debugging if (argc<2) { PrintHelp(); return false; } #endif if (argc<2) serverAddress=DEFAULT_SERVER_ADDRESS; else serverAddress=argv[1]; if (argc<3) serverPort=DEFAULT_SERVER_PORT; else serverPort=atoi(argv[2]); // ---- RAKPEER ----- RakNet::RakPeerInterface *rakPeer; rakPeer=RakNet::RakPeerInterface::GetInstance(); static const unsigned short clientLocalPort=0; RakNet::SocketDescriptor sd(clientLocalPort,0); // Change this if you want RakNet::StartupResult sr = rakPeer->Startup(1,&sd,1); // Change this if you want rakPeer->SetMaximumIncomingConnections(0); // Change this if you want if (sr!=RakNet::RAKNET_STARTED) { printf("Startup failed. Reason=%i\n", (int) sr); return 1; } RakNet::CloudClient cloudClient; rakPeer->AttachPlugin(&cloudClient); RakNet::ConnectionAttemptResult car = rakPeer->Connect(serverAddress, serverPort, 0, 0); if (car==RakNet::CANNOT_RESOLVE_DOMAIN_NAME) { printf("Cannot resolve domain name\n"); return 1; } printf("Connecting to %s...\n", serverAddress); bool didRebalance=false; // So we only reconnect to a lower load server once, for load balancing RakNet::Packet *packet; while (1) { for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive()) { switch (packet->data[0]) { case ID_CONNECTION_LOST: printf("Lost connection to server.\n"); return 1; case ID_CONNECTION_ATTEMPT_FAILED: printf("Failed to connect to server at %s.\n", packet->systemAddress.ToString(true)); return 1; case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY: case ID_OUR_SYSTEM_REQUIRES_SECURITY: case ID_PUBLIC_KEY_MISMATCH: case ID_INVALID_PASSWORD: case ID_CONNECTION_BANNED: // You won't see these unless you modified CloudServer printf("Server rejected the connection.\n"); return 1; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("Server is running an incompatible RakNet version.\n"); return 1; case ID_NO_FREE_INCOMING_CONNECTIONS: printf("Server has no free connections\n"); return 1; case ID_IP_RECENTLY_CONNECTED: printf("Recently connected. Retrying."); rakPeer->Connect(serverAddress, serverPort, 0, 0); break; case ID_CONNECTION_REQUEST_ACCEPTED: printf("Connected to server.\n"); UploadInstanceToCloud(&cloudClient, packet->guid); GetClientSubscription(&cloudClient, packet->guid); GetServers(&cloudClient, packet->guid); break; case ID_CLOUD_GET_RESPONSE: { RakNet::CloudQueryResult cloudQueryResult; cloudClient.OnGetReponse(&cloudQueryResult, packet); unsigned int rowIndex; const bool wasCallToGetServers=cloudQueryResult.cloudQuery.keys[0].primaryKey=="CloudConnCount"; printf("\n"); if (wasCallToGetServers) printf("Downloaded server list. %i servers.\n", cloudQueryResult.rowsReturned.Size()); else printf("Downloaded client list. %i clients.\n", cloudQueryResult.rowsReturned.Size()); unsigned short connectionsOnOurServer=65535; unsigned short lowestConnectionsServer=65535; RakNet::SystemAddress lowestConnectionAddress; for (rowIndex=0; rowIndex < cloudQueryResult.rowsReturned.Size(); rowIndex++) { RakNet::CloudQueryRow *row = cloudQueryResult.rowsReturned[rowIndex]; if (wasCallToGetServers) { unsigned short connCount; RakNet::BitStream bsIn(row->data, row->length, false); bsIn.Read(connCount); printf("%i. Server found at %s with %i connections\n", rowIndex+1, row->serverSystemAddress.ToString(true), connCount); unsigned short connectionsExcludingOurselves; if (row->serverGUID==packet->guid) connectionsExcludingOurselves=connCount-1; else connectionsExcludingOurselves=connCount; // Find the lowest load server (optional) if (packet->guid==row->serverGUID) { connectionsOnOurServer=connectionsExcludingOurselves; } else if (connectionsExcludingOurselves < lowestConnectionsServer) { lowestConnectionsServer=connectionsExcludingOurselves; lowestConnectionAddress=row->serverSystemAddress; } } else { printf("%i. Client found at %s", rowIndex+1, row->clientSystemAddress.ToString(true)); if (row->clientGUID==rakPeer->GetMyGUID()) printf(" (Ourselves)"); RakNet::BitStream bsIn(row->data, row->length, false); RakNet::RakString clientData; bsIn.Read(clientData); printf(" Data: %s", clientData.C_String()); printf("\n"); } } // Do load balancing by reconnecting to lowest load server (optional) if (didRebalance==false && wasCallToGetServers && cloudQueryResult.rowsReturned.Size()>0 && connectionsOnOurServer>lowestConnectionsServer) { printf("Reconnecting to lower load server %s\n", lowestConnectionAddress.ToString(false)); rakPeer->CloseConnection(packet->guid, true); // Wait for the thread to close, otherwise will immediately get back ID_CONNECTION_ATTEMPT_FAILED because no free outgoing connection slots // Alternatively, just call Startup() with 2 slots instead of 1 RakSleep(500); rakPeer->Connect(lowestConnectionAddress.ToString(false), lowestConnectionAddress.GetPort(), 0, 0); didRebalance=true; } cloudClient.DeallocateWithDefaultAllocator(&cloudQueryResult); } break; case ID_CLOUD_SUBSCRIPTION_NOTIFICATION: { bool wasUpdated; RakNet::CloudQueryRow cloudQueryRow; cloudClient.OnSubscriptionNotification(&wasUpdated, &cloudQueryRow, packet, 0 ); if (wasUpdated) printf("New client at %s\n", cloudQueryRow.clientSystemAddress.ToString(true)); else printf("Lost client at %s\n", cloudQueryRow.clientSystemAddress.ToString(true)); cloudClient.DeallocateWithDefaultAllocator(&cloudQueryRow); } break; } } // Any additional client processing can go here RakSleep(30); } RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; }
void Player::ban() const { auto netCtrl = mwmp::Networking::getPtr(); RakNet::SystemAddress addr = netCtrl->getSystemAddress(guid); netCtrl->banAddress(addr.ToString(false)); }
virtual void OnSendAborted( RakNet::SystemAddress systemAddress ) { char str[32]; systemAddress.ToString(true, (char*) str); RAKNET_DEBUG_PRINTF("Send aborted to %s\n", str); }
virtual void OnFilePushesComplete( RakNet::SystemAddress systemAddress, unsigned short setID ) { char str[32]; systemAddress.ToString(true, (char*) str); RAKNET_DEBUG_PRINTF("File pushes complete to %s\n", str); }
bool TetrisServer::Init() { m_interface = RakNet::RakPeerInterface::GetInstance(); RakNet::RakNetStatistics *rss; m_interface->SetIncomingPassword("Rumpelstiltskin", (int)strlen("Rumpelstiltskin")); m_interface->SetTimeoutTime(30000, RakNet::UNASSIGNED_SYSTEM_ADDRESS); // Record the first client that connects to us so we can pass it to the ping function m_clientID = RakNet::UNASSIGNED_SYSTEM_ADDRESS; // Holds user data char* portstring = "1234"; printf("This is a sample implementation of a text based chat server.\n"); printf("Connect to the project 'Chat Example Client'.\n"); printf("Difficulty: Beginner\n\n"); printf("Starting server.\n"); // Starting the server is very simple. 2 players allowed. // 0 means we don't care about a connectionValidationInteger, and false // for low priority threads // I am creating two socketDesciptors, to create two sockets. One using IPV6 and the other IPV4 RakNet::SocketDescriptor socketDescriptors[2]; socketDescriptors[0].port = atoi(portstring); socketDescriptors[0].socketFamily = AF_INET; // Test out IPV4 socketDescriptors[1].port = atoi(portstring); socketDescriptors[1].socketFamily = AF_INET6; // Test out IPV6 bool b = m_interface->Startup(4, socketDescriptors, 2) == RakNet::RAKNET_STARTED; m_interface->SetMaximumIncomingConnections(4); if (!b) { printf("Failed to start dual IPV4 and IPV6 ports. Trying IPV4 only.\n"); // Try again, but leave out IPV6 b = m_interface->Startup(4, socketDescriptors, 1) == RakNet::RAKNET_STARTED; if (!b) { printf("Server failed to start. Terminating.\n"); return false; } } m_interface->SetOccasionalPing(true); m_interface->SetUnreliableTimeout(1000); DataStructures::List< RakNet::RakNetSocket2* > sockets; m_interface->GetSockets(sockets); printf("Socket addresses used by RakNet:\n"); for (unsigned int i = 0; i < sockets.Size(); i++) { printf("%i. %s\n", i + 1, sockets[i]->GetBoundAddress().ToString(true)); } printf("\nMy IP addresses:\n"); for (unsigned int i = 0; i < m_interface->GetNumberOfAddresses(); i++) { RakNet::SystemAddress sa = m_interface->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i); printf("%i. %s (LAN=%i)\n", i + 1, sa.ToString(false), sa.IsLANAddress()); } printf("\nMy GUID is %s\n", m_interface->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); return true; }
void TetrisServer::Loop() { // This sleep keeps RakNet responsive RakSleep(16); // GetPacketIdentifier returns this unsigned char packetIdentifier; for (p = m_interface->Receive(); p; m_interface->DeallocatePacket(p), p = m_interface->Receive()) { // We got a packet, get the identifier with our handy function packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));; break; case ID_NEW_INCOMING_CONNECTION: // Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); m_clientID = p->systemAddress; // Record the player ID of the client printf("Remote internal IDs:\n"); for (int index = 0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++) { RakNet::SystemAddress internalId = m_interface->GetInternalID(p->systemAddress, index); if (internalId != RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("%i. %s\n", index + 1, internalId.ToString(true)); } } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));; break; default: break; } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::B)) { // Message now holds what we want to broadcast char message[2048] = "Hello!"; // message2 is the data to send // strlen(message2)+1 is to send the null terminator // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order // We arbitrarily pick 0 for the ordering stream // RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast // true means broadcast the message to everyone connected m_interface->Send(message, (const int)strlen(message) + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } }
void Network_module::run() { print_config(); using namespace RakNet; int l_addr_count = m_rakpeer->GetNumberOfAddresses(); NET_MOD_INFO("获取到本机IP数量%d个", l_addr_count); for (int i = 0; i < l_addr_count; i++) { RakNet::SystemAddress addr = m_rakpeer->GetLocalIP(i); NET_MOD_INFO("第%d个IP地址为:%s", i + 1, addr.ToString(false)); } RakNet::SocketDescriptor l_socket_descriptor; l_socket_descriptor.port = m_local_port; if (m_rakpeer->Startup(m_max_connection, &l_socket_descriptor, 1) != RakNet::RAKNET_STARTED) { NET_MOD_ERROR("启动网络引擎失败"); RakNet::RakPeerInterface::DestroyInstance(m_rakpeer); return; } m_rakpeer->SetMaximumIncomingConnections(m_max_income_connection); NET_MOD_INFO("启动网络引擎成功,监控地址为%s", m_rakpeer->GetMyBoundAddress().ToString(false)); NET_MOD_INFO("开始载入打孔插件"); m_punch_proxy->init_proxy(m_rakpeer); if (m_rakpeer->Connect(DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, 0, 0) != RakNet::CONNECTION_ATTEMPT_STARTED) { NET_MOD_ERROR("网络引擎,尝试连接失败"); return; } NET_MOD_INFO("尝试连接服务器IP地址为%s,端口为%d", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT); RakNet::Packet* packet = NULL; int flag = true; while (flag) { for (packet=m_rakpeer->Receive(); packet; m_rakpeer->DeallocatePacket(packet), packet=m_rakpeer->Receive()) { if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { NET_MOD_INFO("连接服务器%s:%d成功", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT); if (m_server_addr) { delete m_server_addr; } m_server_addr = new RakNet::SystemAddress; *m_server_addr = packet->systemAddress; flag = false; break; } else { NET_MOD_ERROR("连接服务器失败"); return; } } } start_network_loop(); }
std::string Player::getIP() const { RakNet::SystemAddress addr = mwmp::Networking::getPtr()->getSystemAddress(guid); return addr.ToString(false); }
void Server::update(running_machine *machine) { for( map<RakNet::RakNetGUID,vector< string > >::iterator it = unknownPeerInputs.begin(); it != unknownPeerInputs.end(); ) { cout << "GOT UNKNOWN PEER INPUT\n"; if(peerIDs.find(it->first)!=peerIDs.end()) { int ID = peerIDs[it->first]; for(int a=0;a<it->second.size();a++) { peerInputs[ID].push_back(it->second[a]); } map<RakNet::RakNetGUID,vector< string > >::iterator itold = it; it++; unknownPeerInputs.erase(itold); } else { it++; } } //cout << "SERVER TIME: " << RakNet::GetTimeMS()/1000.0f/60.0f << endl; //printf("Updating server\n"); RakNet::Packet *p; for (p=rakInterface->Receive(); p; rakInterface->DeallocatePacket(p), p=rakInterface->Receive()) { // We got a packet, get the identifier with our handy function unsigned char packetIdentifier = GetPacketIdentifier(p); //printf("GOT PACKET %d\n",int(packetIdentifier)); // Check if this is a network message packet switch (packetIdentifier) { case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true)); removePeer(p->guid,machine); break; case ID_NEW_INCOMING_CONNECTION: // Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); if(syncHappend) { //Sorry, too late //rakInterface->CloseConnection(p->systemAddress,true); } break; case ID_CLIENT_INFO: cout << "GOT ID_CLIENT_INFO\n"; //This client is requesting candidacy, set their info { char buf[4096]; strcpy(buf,(char*)(p->data+1)); candidateNames[p->systemAddress] = buf; } //Find a session index for the player { char buf[4096]; buf[0] = ID_SETTINGS; memcpy(buf+1,&secondsBetweenSync,sizeof(int)); strcpy(buf+1+sizeof(int),username.c_str()); rakInterface->Send( buf, 1+sizeof(int)+username.length()+1, HIGH_PRIORITY, RELIABLE_ORDERED, ORDERING_CHANNEL_SYNC, p->guid, false ); } if(acceptedPeers.size()>=maxPeerID-1) { //Sorry, no room rakInterface->CloseConnection(p->systemAddress,true); } else if(acceptedPeers.size()) { printf("Asking other peers to accept %s\n",p->systemAddress.ToString()); waitingForAcceptFrom[p->systemAddress] = std::vector<RakNet::RakNetGUID>(); for(int a=0; a<acceptedPeers.size(); a++) { RakNet::RakNetGUID guid = acceptedPeers[a]; waitingForAcceptFrom[p->systemAddress].push_back(guid); cout << "SENDING ADVERTIZE TO " << guid.ToString() << endl; char buf[4096]; buf[0] = ID_ADVERTISE_SYSTEM; strcpy(buf+1,p->systemAddress.ToString(true)); rakInterface->Send(buf,1+strlen(p->systemAddress.ToString(true))+1,HIGH_PRIORITY,RELIABLE_ORDERED,ORDERING_CHANNEL_SYNC,guid,false); } printf("Asking other peers to accept\n"); } else { //First client, automatically accept acceptPeer(p->systemAddress,machine); } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_ACCEPT_NEW_HOST: { printf("Accepting new host\n"); RakNet::SystemAddress saToAccept; saToAccept.SetBinaryAddress(((char*)p->data)+1); for(int a=0; a<waitingForAcceptFrom[saToAccept].size(); a++) { if(waitingForAcceptFrom[saToAccept][a]==p->guid) { waitingForAcceptFrom[saToAccept].erase(waitingForAcceptFrom[saToAccept].begin()+a); break; } } if(waitingForAcceptFrom[saToAccept].empty()) { cout << "Accepting: " << saToAccept.ToString() << endl; waitingForAcceptFrom.erase(waitingForAcceptFrom.find(saToAccept)); acceptPeer(saToAccept,machine); } } break; case ID_REJECT_NEW_HOST: { RakNet::SystemAddress saToReject; saToReject.SetBinaryAddress(((char*)p->data)+1); printf("Rejecting new client\n"); cout << p->guid.ToString() << " REJECTS " << saToReject.ToString() << endl; if(waitingForAcceptFrom.find(saToReject)==waitingForAcceptFrom.end()) printf("Could not find waitingForAcceptFrom for this GUID, weird"); else waitingForAcceptFrom.erase(waitingForAcceptFrom.find(saToReject)); rakInterface->CloseConnection(saToReject,true); } break; case ID_CLIENT_INPUTS: if(peerIDs.find(p->guid)==peerIDs.end() || peerInputs.find(peerIDs[p->guid])==peerInputs.end()) { cout << __FILE__ << ":" << __LINE__ << " OOPS!!!!\n"; } //cout << "GOT CLIENT INPUTS\n"; peerInputs[peerIDs[p->guid]].push_back(string((char*)GetPacketData(p),(int)GetPacketSize(p))); break; default: printf("UNEXPECTED PACKET ID: %d\n",int(packetIdentifier)); break; } } }
int main(void) { PortAudioStream *stream; PaError err; mute=false; bool quit; char ch; printf("A sample on how to use RakVoice. You need a microphone for this sample.\n"); printf("RakVoice relies on Speex for voice encoding and decoding.\n"); printf("See DependentExtensions/RakVoice/speex-1.1.12 for speex projects.\n"); printf("For windows, I had to define HAVE_CONFIG_H, include win32/config.h,\n"); printf("and include the files under libspeex, except those that start with test.\n"); printf("PortAudio is also included and is used to read and write audio data. You\n"); printf("can substitute whatever you want if you do not want to use portaudio.\n"); printf("Difficulty: Advanced\n\n"); // Since voice is peer to peer, we give the option to use the nat punchthrough client if desired. RakNet::NatPunchthroughClient natPunchthroughClient; char port[256]; rakPeer = RakNet::RakPeerInterface::GetInstance(); printf("Enter local port (enter for default): "); Gets(port, sizeof(port)); if (port[0]==0) strcpy(port, "60000"); RakNet::SocketDescriptor socketDescriptor(atoi(port),0); rakPeer->Startup(4, &socketDescriptor, 1); rakPeer->SetMaximumIncomingConnections(4); rakPeer->AttachPlugin(&rakVoice); rakPeer->AttachPlugin(&natPunchthroughClient); rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER*sizeof(SAMPLE)); err = Pa_Initialize(); if( err != paNoError ) goto error; err = Pa_OpenStream( &stream, Pa_GetDefaultInputDeviceID(), 1, // Num channels, whatever that means PA_SAMPLE_TYPE, NULL, Pa_GetDefaultOutputDeviceID(), 1, // Num channels PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 0, /* paDitherOff, // flags */ PACallback, 0 ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Support NAT punchthrough? (y/n)? "); bool useNatPunchthrough; useNatPunchthrough=(getche()=='y'); printf("\n"); char facilitatorIP[256]; {//Linux fix. Won't compile without it. Because of the goto error above, the scope is ambigious. Make it a block to define that it will not be used after the jump. //Doesn't change current logic RakNet::SystemAddress facilitator; if (useNatPunchthrough) { printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); printf("Enter IP of facilitator (enter for default): "); Gets(facilitatorIP,sizeof(facilitatorIP)); if (facilitatorIP[0]==0) strcpy(facilitatorIP, "natpunch.jenkinssoftware.com"); facilitator.FromString(facilitatorIP); facilitator.SetPortHostOrder(NAT_PUNCHTHROUGH_FACILITATOR_PORT); rakPeer->Connect(facilitatorIP, NAT_PUNCHTHROUGH_FACILITATOR_PORT, 0, 0); printf("Connecting to facilitator...\n"); } else { printf("Not supporting NAT punchthrough.\n"); } RakNet::Packet *p; quit=false; if (useNatPunchthrough==false) printf("(Q)uit. (C)onnect. (D)isconnect. C(l)ose voice channels. (M)ute. ' ' for stats.\n"); while (!quit) { if (kbhit()) { ch=getch(); if (ch=='y') { quit=true; } else if (ch=='c') { if (useNatPunchthrough) { RakNet::RakNetGUID destination; printf("Enter GUID of destination: "); char guidStr[256]; while (1) { Gets(guidStr,sizeof(guidStr)); if (!destination.FromString(guidStr)) printf("Invalid GUID format. Try again.\nEnter GUID of destination: "); else break; } printf("Starting NAT punch. Please wait...\n"); natPunchthroughClient.OpenNAT(destination,facilitator); } else { char ip[256]; printf("Enter IP of remote system: "); Gets(ip, sizeof(ip)); if (ip[0]==0) strcpy(ip, "127.0.0.1"); printf("Enter port of remote system: "); Gets(port, sizeof(port)); if (port[0]==0) strcpy(port, "60000"); rakPeer->Connect(ip, atoi(port), 0,0); } } else if (ch=='m') { mute=!mute; if (mute) printf("Now muted.\n"); else printf("No longer muted.\n"); } else if (ch=='d') { rakPeer->Shutdown(100,0); } else if (ch=='l') { rakVoice.CloseAllChannels(); } else if (ch==' ') { char message[2048]; RakNet::RakNetStatistics *rss=rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); } else if (ch=='q') quit=true; ch=0; } p=rakPeer->Receive(); while (p) { if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { if (p->systemAddress==facilitator) { printf("Connection to facilitator completed\n"); printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); } else { printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString()); rakVoice.RequestVoiceChannel(p->guid); } } else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) { if (p->systemAddress==facilitator) { printf("Connection to facilitator failed. Using direct connections\n"); useNatPunchthrough=false; printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); } else { printf("ID_CONNECTION_ATTEMPT_FAILED\n"); } } else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY) { printf("Got new channel from %s\n", p->systemAddress.ToString()); } else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED) { printf("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED) { printf("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString()); rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.GetPort(),0,0); } else if (p->data[0]==ID_ALREADY_CONNECTED) { printf("ID_ALREADY_CONNECTED\n"); } else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL) { printf("ID_RAKVOICE_CLOSE_CHANNEL\n"); } else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION) { printf("ID_DISCONNECTION_NOTIFICATION\n"); } else if (p->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION\n"); } else { printf("Unknown packet ID %i\n", p->data[0]); } rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } Pa_Sleep( 30 ); } } err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); rakPeer->Shutdown(300); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; error: Pa_Terminate(); fprintf( stderr, "An error occured while using the portaudio stream\n" ); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return -1; }
_CONSOLE_2_SetSystemProcessParams #endif int main(void) { // Pointers to the interfaces of our server and client. // Note we can easily have both in the same program RakNet::RakPeerInterface *server=RakNet::RakPeerInterface::GetInstance(); RakNet::RakNetStatistics *rss; server->SetIncomingPassword("Rumpelstiltskin", (int)strlen("Rumpelstiltskin")); server->SetTimeoutTime(30000,RakNet::UNASSIGNED_SYSTEM_ADDRESS); // RakNet::PacketLogger packetLogger; // server->AttachPlugin(&packetLogger); #if LIBCAT_SECURITY==1 cat::EasyHandshake handshake; char public_key[cat::EasyHandshake::PUBLIC_KEY_BYTES]; char private_key[cat::EasyHandshake::PRIVATE_KEY_BYTES]; handshake.GenerateServerKey(public_key, private_key); server->InitializeSecurity(public_key, private_key, false); FILE *fp = fopen("publicKey.dat","wb"); fwrite(public_key,sizeof(public_key),1,fp); fclose(fp); #endif // Holds packets RakNet::Packet* p; // GetPacketIdentifier returns this unsigned char packetIdentifier; // Record the first client that connects to us so we can pass it to the ping function RakNet::SystemAddress clientID=RakNet::UNASSIGNED_SYSTEM_ADDRESS; // Holds user data char portstring[30]; printf("This is a sample implementation of a text based chat server.\n"); printf("Connect to the project 'Chat Example Client'.\n"); printf("Difficulty: Beginner\n\n"); // A server puts("Enter the server port to listen on"); Gets(portstring,sizeof(portstring)); if (portstring[0]==0) strcpy(portstring, "1234"); puts("Starting server."); // Starting the server is very simple. 2 players allowed. // 0 means we don't care about a connectionValidationInteger, and false // for low priority threads // I am creating two socketDesciptors, to create two sockets. One using IPV6 and the other IPV4 RakNet::SocketDescriptor socketDescriptors[2]; socketDescriptors[0].port=atoi(portstring); socketDescriptors[0].socketFamily=AF_INET; // Test out IPV4 socketDescriptors[1].port=atoi(portstring); socketDescriptors[1].socketFamily=AF_INET6; // Test out IPV6 bool b = server->Startup(4, socketDescriptors, 2 )==RakNet::RAKNET_STARTED; server->SetMaximumIncomingConnections(4); if (!b) { printf("Failed to start dual IPV4 and IPV6 ports. Trying IPV4 only.\n"); // Try again, but leave out IPV6 b = server->Startup(4, socketDescriptors, 1 )==RakNet::RAKNET_STARTED; if (!b) { puts("Server failed to start. Terminating."); exit(1); } } server->SetOccasionalPing(true); server->SetUnreliableTimeout(1000); DataStructures::List< RakNet::RakNetSocket2* > sockets; server->GetSockets(sockets); printf("Socket addresses used by RakNet:\n"); for (unsigned int i=0; i < sockets.Size(); i++) { printf("%i. %s\n", i+1, sockets[i]->GetBoundAddress().ToString(true)); } printf("\nMy IP addresses:\n"); for (unsigned int i=0; i < server->GetNumberOfAddresses(); i++) { RakNet::SystemAddress sa = server->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i); printf("%i. %s (LAN=%i)\n", i+1, sa.ToString(false), sa.IsLANAddress()); } printf("\nMy GUID is %s\n", server->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); puts("'quit' to quit. 'stat' to show stats. 'ping' to ping.\n'pingip' to ping an ip address\n'ban' to ban an IP from connecting.\n'kick to kick the first connected player.\nType to talk."); char message[2048]; // Loop for input while (1) { // This sleep keeps RakNet responsive RakSleep(30); if (kbhit()) { // Notice what is not here: something to keep our network running. It's // fine to block on gets or anything we want // Because the network engine was painstakingly written using threads. Gets(message,sizeof(message)); if (strcmp(message, "quit")==0) { puts("Quitting."); break; } if (strcmp(message, "stat")==0) { rss=server->GetStatistics(server->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); printf("Ping %i\n", server->GetAveragePing(server->GetSystemAddressFromIndex(0))); continue; } if (strcmp(message, "ping")==0) { server->Ping(clientID); continue; } if (strcmp(message, "pingip")==0) { printf("Enter IP: "); Gets(message,sizeof(message)); printf("Enter port: "); Gets(portstring,sizeof(portstring)); if (portstring[0]==0) strcpy(portstring, "1234"); server->Ping(message, atoi(portstring), false); continue; } if (strcmp(message, "kick")==0) { server->CloseConnection(clientID, true, 0); continue; } if (strcmp(message, "getconnectionlist")==0) { RakNet::SystemAddress systems[10]; unsigned short numConnections=10; server->GetConnectionList((RakNet::SystemAddress*) &systems, &numConnections); for (int i=0; i < numConnections; i++) { printf("%i. %s\n", i+1, systems[i].ToString(true)); } continue; } if (strcmp(message, "ban")==0) { printf("Enter IP to ban. You can use * as a wildcard\n"); Gets(message,sizeof(message)); server->AddToBanList(message); printf("IP %s added to ban list.\n", message); continue; } // Message now holds what we want to broadcast char message2[2048]; // Append Server: to the message so clients know that it ORIGINATED from the server // All messages to all clients come from the server either directly or by being // relayed from other clients message2[0]=0; strcpy(message2, "Server: "); strcat(message2, message); // message2 is the data to send // strlen(message2)+1 is to send the null terminator // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order // We arbitrarily pick 0 for the ordering stream // RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast // true means broadcast the message to everyone connected server->Send(message2, (const int) strlen(message2)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } // Get a packet from either the server or the client for (p=server->Receive(); p; server->DeallocatePacket(p), p=server->Receive()) { // We got a packet, get the identifier with our handy function packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));; break; case ID_NEW_INCOMING_CONNECTION: // Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); clientID=p->systemAddress; // Record the player ID of the client printf("Remote internal IDs:\n"); for (int index=0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++) { RakNet::SystemAddress internalId = server->GetInternalID(p->systemAddress, index); if (internalId!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("%i. %s\n", index+1, internalId.ToString(true)); } } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));; break; default: // The server knows the static data of all clients, so we can prefix the message // With the name data printf("%s\n", p->data); // Relay the message. We prefix the name for other clients. This demonstrates // That messages can be changed on the server before being broadcast // Sending is the same as before sprintf(message, "%s", p->data); server->Send(message, (const int) strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; } } } server->Shutdown(300); // We're done with the network RakNet::RakPeerInterface::DestroyInstance(server); return 0; }
bool Connector::startAsServer(unsigned short maxPlayers) { server = RakNet::UNASSIGNED_SYSTEM_ADDRESS; // raknet interface configuration raknetInterface= RakNet::RakPeerInterface::GetInstance(); raknetInterface->SetTimeoutTime(CONNECTION_LOST_TIMEOUT, RakNet::UNASSIGNED_SYSTEM_ADDRESS); raknetInterface->SetOccasionalPing(true); raknetInterface->SetIncomingPassword(RAKNET_PASSWORD, strlen(RAKNET_PASSWORD)); raknetInterface->SetMaximumIncomingConnections(maxPlayers); // socket descriptor settings RakNet::SocketDescriptor socketDescriptors[1]; socketDescriptors[0].port = (maxPlayers>1) ? SERVER_PORT : CLIENT_PORT; socketDescriptors[0].socketFamily=AF_INET; // IPV4 // try 10 ports bool result = false; for(int i=0; i<PORT_RANGE; i++) { result = raknetInterface->Startup(maxPlayers, socketDescriptors, 1) == RakNet::RAKNET_STARTED; // last arg is socketDescriptor count if(result == true) { LOG("Servers started on port %d.\n", socketDescriptors[0].port); break; } else { LOG("Server failed to start on port %d. Trying next...\n", socketDescriptors[0].port); socketDescriptors[0].port++; continue; } } if (result == false){ LOG("Server failed to start on EACH PORT!!.\n"); RakNet::RakPeerInterface::DestroyInstance(raknetInterface); raknetInterface = nullptr; return false; } // logging used socket addresses DataStructures::List< RakNet::RakNetSocket2* > sockets; raknetInterface->GetSockets(sockets); /*LOG("Socket addresses used by Connector:\n==========================\n"); for (unsigned int i=0; i < sockets.Size(); i++) { LOG("%i. %s\n", i+1, sockets[i]->GetBoundAddress().ToString(true)); }*/ LOG("\nMy IP addresses:\n"); for (unsigned int i = 0; i < raknetInterface->GetNumberOfAddresses(); i++) { RakNet::SystemAddress sa = raknetInterface->GetInternalID(RakNet::UNASSIGNED_SYSTEM_ADDRESS, i); LOG("%i. %s:%i\n", i+1, sa.ToString(false), sa.GetPort()); } // server name if(maxPlayers>1){ raknetInterface->SetOfflinePingResponse("Unnamed Server", strlen("Unnamed Server") + 1); // '\0' is automatically added in "hello" } return true; }
int main(int argc, char** argv) { RakNet::RakPeerInterface *server = RakNet::RakPeerInterface::GetInstance(); RakNet::Packet* p; unsigned char packetIdentifier; RakNet::SystemAddress clientID = RakNet::UNASSIGNED_SYSTEM_ADDRESS; RakNet::RakNetStatistics *rss; RakNet::SocketDescriptor socketDescriptors[2]; char portstring[30]; socketDescriptors[0].port = SERVER_PORT; socketDescriptors[0].socketFamily = AF_INET; // Test out IPV4 socketDescriptors[1].port = SERVER_PORT; socketDescriptors[1].socketFamily = AF_INET6; // Test out IPV6 if (server->Startup(4, socketDescriptors, 2) != RakNet::RAKNET_STARTED) { std::cout << "IPV6 not supported, starting with IPV4-only interface..." << std::endl; if (server->Startup(4, socketDescriptors, 1) != RakNet::RAKNET_STARTED) { std::cerr << "Error creating server, exiting..." << std::endl; exit(-1); } } std::cout << "Server started successfully. Listening on port " << SERVER_PORT << std::endl; server->SetMaximumIncomingConnections(20); server->SetOccasionalPing(true); server->SetUnreliableTimeout(1000); DataStructures::List<RakNet::RakNetSocket2*> sockets; server->GetSockets(sockets); std::cout << "Socket addresses used by RakNet:" << std::endl; for (unsigned int i = 0; i < sockets.Size(); i++) { printf("%i. %s\n", i + 1, sockets[i]->GetBoundAddress().ToString(true)); } char message[2048]; // Loop for input while (1) { // This sleep keeps RakNet responsive RakSleep(30); if (kbhit()) { // Notice what is not here: something to keep our network running. It's // fine to block on gets or anything we want // Because the network engine was painstakingly written using threads. Gets(message, sizeof(message)); if (strcmp(message, "quit") == 0) { puts("Quitting."); break; } if (strcmp(message, "stat") == 0) { rss = server->GetStatistics(server->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); printf("Ping %i\n", server->GetAveragePing(server->GetSystemAddressFromIndex(0))); continue; } if (strcmp(message, "ping") == 0) { server->Ping(clientID); continue; } if (strcmp(message, "pingip") == 0) { printf("Enter IP: "); Gets(message, sizeof(message)); printf("Enter port: "); Gets(portstring, sizeof(portstring)); if (portstring[0] == 0) strcpy(portstring, "1234"); server->Ping(message, atoi(portstring), false); continue; } if (strcmp(message, "kick") == 0) { server->CloseConnection(clientID, true, 0); continue; } if (strcmp(message, "getconnectionlist") == 0) { printf("Connections:\n"); RakNet::SystemAddress systems[10]; unsigned short numConnections = 10; server->GetConnectionList((RakNet::SystemAddress*) &systems, &numConnections); for (int i = 0; i < numConnections; i++) { printf("%i. %s\n", i + 1, systems[i].ToString(true)); } continue; } if (strcmp(message, "ban") == 0) { printf("Enter IP to ban. You can use * as a wildcard\n"); Gets(message, sizeof(message)); server->AddToBanList(message); printf("IP %s added to ban list.\n", message); continue; } // Message now holds what we want to broadcast char message2[2048]; // Append Server: to the message so clients know that it ORIGINATED from the server // All messages to all clients come from the server either directly or by being // relayed from other clients message2[0] = 0; const static char prefix[] = "Server: "; strncpy(message2, prefix, sizeof(message2)); strncat(message2, message, sizeof(message2) - strlen(prefix) - 1); // message2 is the data to send // strlen(message2)+1 is to send the null terminator // HIGH_PRIORITY doesn't actually matter here because we don't use any other priority // RELIABLE_ORDERED means make sure the message arrives in the right order // We arbitrarily pick 0 for the ordering stream // RakNet::UNASSIGNED_SYSTEM_ADDRESS means don't exclude anyone from the broadcast // true means broadcast the message to everyone connected server->Send(message2, (const int)strlen(message2) + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } // Get a packet from either the server or the client for (p = server->Receive(); p; server->DeallocatePacket(p), p = server->Receive()) { // We got a packet, get the identifier with our handy function packetIdentifier = GetPacketIdentifier(p); // Check if this is a network message packet switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));; break; case ID_NEW_INCOMING_CONNECTION: // Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); clientID = p->systemAddress; // Record the player ID of the client printf("Remote internal IDs:\n"); for (int index = 0; index < MAXIMUM_NUMBER_OF_INTERNAL_IDS; index++) { RakNet::SystemAddress internalId = server->GetInternalID(p->systemAddress, index); if (internalId != RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("%i. %s\n", index + 1, internalId.ToString(true)); } } break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_CONNECTED_PING: case ID_UNCONNECTED_PING: printf("Ping from %s\n", p->systemAddress.ToString(true)); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST from %s\n", p->systemAddress.ToString(true));; break; default: // The server knows the static data of all clients, so we can prefix the message // With the name data printf("%s\n", p->data); // Relay the message. We prefix the name for other clients. This demonstrates // That messages can be changed on the server before being broadcast // Sending is the same as before sprintf(message, "%s", p->data); server->Send(message, (const int)strlen(message) + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; } } } server->Shutdown(300); // We're done with the network RakNet::RakPeerInterface::DestroyInstance(server); }
void SimulateClientMainFrame::OnSend( wxCommandEvent& event ) { wxString serverName=m_serverList->GetStringSelection(); wxString messageID=m_messagelist->GetStringSelection(); wxString message= m_MessageText->GetValue(); //if(serverName.empty()||messageID.empty()||messageID.empty()) //{ // wxMessageBox("请选择服务器,消息id,和消息内容"); // return ; //} unsigned int id=stringToMessageID(messageID.c_str()); RakNet::SystemAddress address; address.SetBinaryAddress(serverName.c_str()); if(id==GM_TEXT_MESSAGE) { NetWorkClient::getSingletonPtr()->getConnectInstance("statserver")->send(id,message.c_str(),message.Length()+1); m_MessageText->Clear(); addSendMessage(message); }else if(GM_ACCOUNT_REQUEST==id) { UserLogin userlogin; ::ZeroMemory(&userlogin,sizeof(userlogin)); if(sscanf(message.c_str(),"%s = %s",userlogin.m_account,userlogin.m_password)>0) { NetWorkClient::getSingleton().getConnectInstance("statserver")->send(id,userlogin); }else { wxMessageBox("格式不正确请用;分格开用户名和密码"); } // memcpy(userlogin.m_account,"palyer1",strlen("player1")); // memcpy(userlogin.m_password,"palyer1",strlen("player1")); }else if(id==GM_CHATMESSAGE) { NetWorkClient::getSingletonPtr()->getConnectInstance(GAMESERVER)->send(id,message.c_str(),message.Length()+1); m_MessageText->Clear(); addSendMessage(message); }else if(id==GM_CONNECT_GAMESERVER) { ///发送帐号id组游戏逻辑服务器 long accountid=0; if(message.ToLong(&accountid)) { UINT temid=accountid; NetWorkClient::getSingletonPtr()->getConnectInstance(GAMESERVER)->send(id,temid); m_MessageText->Clear(); } } return ; }
int main(int argc, char **argv) { if (argc<8) { printf("Arguments: serverIP, pathToGame, gameName, patchImmediately, localPort, serverPort, fullScan"); return 0; } RakNet::SystemAddress TCPServerAddress=RakNet::UNASSIGNED_SYSTEM_ADDRESS; RakNet::AutopatcherClient autopatcherClient; RakNet::FileListTransfer fileListTransfer; RakNet::CloudClient cloudClient; autopatcherClient.SetFileListTransferPlugin(&fileListTransfer); bool didRebalance=false; // So we only reconnect to a lower load server once, for load balancing bool fullScan = argv[7][0]=='1'; unsigned short localPort; localPort=atoi(argv[5]); unsigned short serverPort=atoi(argv[6]); RakNet::PacketizedTCP packetizedTCP; if (packetizedTCP.Start(localPort,1)==false) { printf("Failed to start TCP. Is the port already in use?"); return 1; } packetizedTCP.AttachPlugin(&autopatcherClient); packetizedTCP.AttachPlugin(&fileListTransfer); RakNet::RakPeerInterface *rakPeer; rakPeer = RakNet::RakPeerInterface::GetInstance(); RakNet::SocketDescriptor socketDescriptor(localPort,0); rakPeer->Startup(1,&socketDescriptor, 1); rakPeer->AttachPlugin(&cloudClient); DataStructures::List<RakNet::RakNetSocket2* > sockets; rakPeer->GetSockets(sockets); printf("Started on port %i\n", sockets[0]->GetBoundAddress().GetPort()); char buff[512]; strcpy(buff, argv[1]); rakPeer->Connect(buff, serverPort, 0, 0); printf("Connecting...\n"); char appDir[512]; strcpy(appDir, argv[2]); char appName[512]; strcpy(appName, argv[3]); bool patchImmediately=argc>=5 && argv[4][0]=='1'; RakNet::Packet *p; while (1) { RakNet::SystemAddress notificationAddress; notificationAddress=packetizedTCP.HasCompletedConnectionAttempt(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); TCPServerAddress=notificationAddress; } notificationAddress=packetizedTCP.HasNewIncomingConnection(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("ID_NEW_INCOMING_CONNECTION\n"); notificationAddress=packetizedTCP.HasLostConnection(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("ID_CONNECTION_LOST\n"); notificationAddress=packetizedTCP.HasFailedConnectionAttempt(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("ID_CONNECTION_ATTEMPT_FAILED TCP\n"); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } p=packetizedTCP.Receive(); while (p) { if (p->data[0]==ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR) { char buff[256]; RakNet::BitStream temp(p->data, p->length, false); temp.IgnoreBits(8); RakNet::StringCompressor::Instance()->DecodeString(buff, 256, &temp); printf("ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR\n"); printf("%s\n", buff); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } else if (p->data[0]==ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES) { printf("ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES\n"); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } else if (p->data[0]==ID_AUTOPATCHER_FINISHED) { printf("ID_AUTOPATCHER_FINISHED with server time %f\n", autopatcherClient.GetServerDate()); double srvDate=autopatcherClient.GetServerDate(); FILE *fp = fopen("srvDate", "wb"); fwrite(&srvDate,sizeof(double),1,fp); fclose(fp); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } else if (p->data[0]==ID_AUTOPATCHER_RESTART_APPLICATION) { printf("ID_AUTOPATCHER_RESTART_APPLICATION"); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } // Launch \"AutopatcherClientRestarter.exe autopatcherRestart.txt\"\nQuit this application immediately after to unlock files.\n"); packetizedTCP.DeallocatePacket(p); p=packetizedTCP.Receive(); } p=rakPeer->Receive(); while (p) { if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { // UploadInstanceToCloud(&cloudClient, p->guid); // GetClientSubscription(&cloudClient, p->guid); GetServers(&cloudClient, p->guid); break; } else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) { printf("ID_CONNECTION_ATTEMPT_FAILED UDP\n"); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } else if (p->data[0]==ID_CLOUD_GET_RESPONSE) { RakNet::CloudQueryResult cloudQueryResult; cloudClient.OnGetReponse(&cloudQueryResult, p); unsigned int rowIndex; const bool wasCallToGetServers=cloudQueryResult.cloudQuery.keys[0].primaryKey=="CloudConnCount"; printf("\n"); if (wasCallToGetServers) printf("Downloaded server list. %i servers.\n", cloudQueryResult.rowsReturned.Size()); unsigned short connectionsOnOurServer=65535; unsigned short lowestConnectionsServer=65535; RakNet::SystemAddress lowestConnectionAddress; for (rowIndex=0; rowIndex < cloudQueryResult.rowsReturned.Size(); rowIndex++) { RakNet::CloudQueryRow *row = cloudQueryResult.rowsReturned[rowIndex]; if (wasCallToGetServers) { unsigned short connCount; RakNet::BitStream bsIn(row->data, row->length, false); bsIn.Read(connCount); printf("%i. Server found at %s with %i connections\n", rowIndex+1, row->serverSystemAddress.ToString(true), connCount); unsigned short connectionsExcludingOurselves; if (row->serverGUID==p->guid) connectionsExcludingOurselves=connCount-1; else connectionsExcludingOurselves=connCount; // Find the lowest load server (optional) if (p->guid==row->serverGUID) { connectionsOnOurServer=connectionsExcludingOurselves; } else if (connectionsExcludingOurselves < lowestConnectionsServer) { lowestConnectionsServer=connectionsExcludingOurselves; lowestConnectionAddress=row->serverSystemAddress; } } } // Do load balancing by reconnecting to lowest load server (optional) if (didRebalance==false && wasCallToGetServers) { if (cloudQueryResult.rowsReturned.Size()>0 && connectionsOnOurServer>lowestConnectionsServer) { printf("Reconnecting to lower load server %s\n", lowestConnectionAddress.ToString(false)); rakPeer->CloseConnection(p->guid, true); // Wait for the thread to close, otherwise will immediately get back ID_CONNECTION_ATTEMPT_FAILED because no free outgoing connection slots // Alternatively, just call Startup() with 2 slots instead of 1 RakSleep(500); rakPeer->Connect(lowestConnectionAddress.ToString(false), lowestConnectionAddress.GetPort(), 0, 0); // TCP Connect to new IP address packetizedTCP.Connect(lowestConnectionAddress.ToString(false),serverPort,false); } else { // TCP Connect to original IP address packetizedTCP.Connect(buff,serverPort,false); } didRebalance=true; } cloudClient.DeallocateWithDefaultAllocator(&cloudQueryResult); } rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } if (TCPServerAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS && patchImmediately==true) { patchImmediately=false; char restartFile[512]; strcpy(restartFile, appDir); strcat(restartFile, "/autopatcherRestart.txt"); double lastUpdateDate; if (fullScan==false) { FILE *fp = fopen("srvDate", "rb"); if (fp) { fread(&lastUpdateDate, sizeof(lastUpdateDate), 1, fp); fclose(fp); } else lastUpdateDate=0; } else lastUpdateDate=0; if (autopatcherClient.PatchApplication(appName, appDir, lastUpdateDate, TCPServerAddress, &transferCallback, restartFile, argv[0])) { printf("Patching process starting.\n"); } else { printf("Failed to start patching.\n"); autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; } } RakSleep(30); } // Dereference so the destructor doesn't crash autopatcherClient.SetFileListTransferPlugin(0); autopatcherClient.Clear(); packetizedTCP.Stop(); rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 1; }