예제 #1
0
	void NetworkManager::init(const bool server, Player *me, const std::string& peer, const int port)
	{
		iamserver = server;
		dout(1, NETWORK) << "Initializing network " << (server ? "server " : "client ")
		<< (me ? "with player" : "without player") << "\n";
		Player::myPlayer = me;
		SocketDescriptor sd;
		if (iamserver)
			sd.port = port;
		else
			sd.port = 0;
		// The network ID authority is the system that creates the common numerical identifier used to lookup pointers.
		// For client/server this is the server
		// For peer to peer this would be true on every system, and you would also have call NetworkID::peerToPeerMode=true;
		networkIdManager.SetIsNetworkIDAuthority(iamserver);
		// Start RakNet, up to 32 connections if the server
		rakPeer->Startup(iamserver ? 32 : 1,0,&sd,1);
		// Start occasional pinging - without which timestamping wouldn't work
		rakPeer->SetOccasionalPing(true);
		// Register our custom connection factory
		replicaManager.SetConnectionFactory(&connectionFactory);
		if (!objectFactory)
			objectFactory = new ObjectFactory;
		// The server should allow systems to connect. Clients do not need to unless you want to use RakVoice or for some other reason want to transmit directly between systems.
		if (iamserver)
			rakPeer->SetMaximumIncomingConnections(32);
		
		if (!iamserver) {
			rakPeer->Connect(peer.c_str(), port, 0, 0, 0);
			dout(1, NETWORK) << "Connecting to " << peer << ":" << port << "\n";
		} else
			dout(1, NETWORK) << "Accepting connections on port " << port << "\n";
		
		systemAddress = serverAddress = rakPeer->GetExternalID(UNASSIGNED_SYSTEM_ADDRESS);

		if (iamserver && !Client::me() && Player::me()) {
			Client *client = new Client;
			Client::mine = client;
			client->SetReplicaManager(&replicaManager);
			client->setSystemAddress(systemAddress);
			client->setConnected(true);
			client->BroadcastConstruction();
			client->AddAutoSerializeTimer(100);
			Player::me()->setOwner(client);
			dout(3, NETWORK) << "  created server client " << client->toString() << "\n";
		}

		active = true;
	}
예제 #2
0
	void NetworkManager::update(const double dt)
	{
		if (!active || !rakPeer)
			return;
		if (Client::me() && Player::me() && !Player::me()->isConstructed()) {
			dout(6, NETWORK) << "Constructing my player\n";
			Client::me()->setPlayer(Player::me());
			Player::me()->construct();
		}
		Packet *packet;
		for (packet = rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet = rakPeer->Receive())
		{
			switch (packet->data[0])
			{
				case ID_CONNECTION_ATTEMPT_FAILED:
					connected = false;
					dout(0, NETWORK) << "Connection attempt failed\n";
					for (ListenerList::iterator i = listeners.begin(); i != listeners.end(); i++)
						(*i)->onConnectionFailed();
					break;
				case ID_NO_FREE_INCOMING_CONNECTIONS:
					dout(0, NETWORK) << "No free incoming connections\n";
					for (ListenerList::iterator i = listeners.begin(); i != listeners.end(); i++)
						(*i)->onNoFreeIncomingConnections();
					break;
				case ID_CONNECTION_REQUEST_ACCEPTED:
				{
					systemAddress = rakPeer->GetExternalID(UNASSIGNED_SYSTEM_ADDRESS);
					
					dout(1, NETWORK) << "Connection request accepted\n";
					dout(3, NETWORK) << "  my address is " << systemAddress.ToString() << "\n";
					short unsigned int num = 1;
					rakPeer->GetConnectionList(&serverAddress,&num);
					connected = true;
					
					connectionHistory.push_back(serverAddress);
					rakPeer->Ping(serverAddress);
					
					for (ListenerList::iterator i = listeners.begin(); i != listeners.end(); i++)
						(*i)->onConnect(NULL);
				}
					break;
				case ID_NEW_INCOMING_CONNECTION:
					dout(0, NETWORK) << "New incoming connection from " << packet->systemAddress.ToString() << "\n";
					connected = true;
				{
					systemAddress = serverAddress = rakPeer->GetExternalID(packet->systemAddress);
					
					Client *client = new Client;
					client->SetReplicaManager(&replicaManager);
					client->setSystemAddress(packet->systemAddress);
					client->setConnected(true);
					client->BroadcastConstruction();
					client->AddAutoSerializeTimer(100);
					dout(3, NETWORK) << "  created client " << client->toString() << "\n";
					
					connectionHistory.push_back(packet->systemAddress);
					rakPeer->Ping(packet->systemAddress);
					
					for (ListenerList::iterator i = listeners.begin(); i != listeners.end(); i++)
						(*i)->onConnect(client);
					
				}				
					break;
				case ID_DISCONNECTION_NOTIFICATION:
					dout(0, NETWORK) << "Disconnect from " << packet->systemAddress.ToString() << "\n";
					for (ListenerList::iterator i = listeners.begin(); i != listeners.end(); i++)
						(*i)->onDisconnect(Client::getClientByAddress(packet->systemAddress));
					if (iamserver) {
						Client *client = Client::getClientByAddress(packet->systemAddress);
						if (!client)
							dout(ERROR, NETWORK) << "Disconnect from unknown client with address" << packet->systemAddress.ToString() << "\n";
						else
							client->setConnected(false);
						takeObjectsFromClient(client);
					} else
						shutdown();
					break;
				case ID_CONNECTION_LOST:
					dout(0, NETWORK) << "Connection lost from " << packet->systemAddress.ToString() << "\n";
					for (ListenerList::iterator i = listeners.begin(); i != listeners.end(); i++)
						(*i)->onConnectionLost(Client::getClientByAddress(packet->systemAddress));
					if (iamserver) {
						Client *client = Client::getClientByAddress(packet->systemAddress);
						if (!client)
							dout(ERROR, NETWORK) << "Connection lost from unknown client with address" << packet->systemAddress.ToString() << "\n";
						else
							client->setConnected(false);
						takeObjectsFromClient(client);
					} else
						shutdown();
					break;
				default:
					dout(WARN, NETWORK) << "Unknown packet ID " << (int) packet->data[0] << "\n";
			}
			//rakPeer->DeallocatePacket(packet);
			//RakSleep(100);
		}
	}