コード例 #1
0
ファイル: CommunicationManager.cpp プロジェクト: Hindi/Moba2D
void CommunicationManager::readOrder(Client* client, sf::Packet packet)
{
	//On récupère la première partie du packet
		std::string firstPart;
		if(packet >> firstPart)
		{
			if(strcmp(firstPart.data(), "ping") == 0)
			{
				//Si c'est un ping, on renvoie pong en réponse
				std::cout << "ping" << std::endl;
				packet.clear();
				packet << "pong";
				client->socket().send(packet);
			}
			if(strcmp(firstPart.data(), "chat") == 0)
			{
				//Si c'est un chat, on récupère la deuxieme partie
				//et on la relaie aux autres joueurs
				std::string secondPart;
				packet >> secondPart;
				for (std::list<Client*>::iterator it = m_clients.begin(); it != m_clients.end(); ++it)
					sendChatMessage((*it), secondPart);
			}
			if(firstPart.compare("myNameIs") == 0)
				packet >> client->m_name;
		}
コード例 #2
0
SocketStatus NetworkManager::receive(sf::Packet& PacketToReceive)
{
    // initialize pendingPacket
    std::vector<char> myPendingPacket;    
    myPendingPacket.clear();
    // We start by getting the size of the incoming packet
    sf::Uint32      PacketSize = 0;
    std::size_t Received   = 0;
    
	PacketSize =receiveB<sf::Uint32>();	
	PacketSize = ntohl(PacketSize);

    // Then loop until we receive all the packet data
    char Buffer[1024];
    while (myPendingPacket.size() < PacketSize)
    {
        // Receive a chunk of data
        std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer));
        SocketStatus Status = Receive(Buffer, SizeToGet, Received);
        if (Status != Done)
        {
			throw std::runtime_error("Network : receive packet : receive of information didn't worked");
        }

        // Append it into the packet
        if (Received > 0)
        {
            myPendingPacket.resize(myPendingPacket.size() + Received);
            char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received;
            memcpy(Begin, Buffer, Received);
        }
    }

    // We have received all the datas : we can copy it to the user packet, and clear our internal packet
    PacketToReceive.Clear();
    if (!myPendingPacket.empty())
        PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size());

    return Done;
}
コード例 #3
0
ファイル: Client.cpp プロジェクト: Stazer/PhatChat
void PhatChat::Server::Client::handlePacket ( sf::Packet packet )
{
	unsigned char operationCodeValue = 0 ;
	packet >> operationCodeValue ;
	PhatChat::OperationCode operationCode = static_cast <PhatChat::OperationCode> ( operationCodeValue ) ;

	if ( operationCode == PhatChat::OperationCode::PING )
	{
		PhatChat::PingPacket pingPacket ( PhatChat::PingPacket::decode ( packet ) ) ;
		std::cout << "Received ping packet with value " << pingPacket.getValue ( ) << "!" << std::endl ;

		sf::Packet newPacket ( PhatChat::PongPacket ( pingPacket.getValue ( ) ).encode ( ) ) ;

        this->socket.send ( newPacket ) ;
	}
	else if ( operationCode == PhatChat::OperationCode::PONG )
	{
		PhatChat::PongPacket pongPacket = PhatChat::PongPacket::decode ( packet ) ;
		std::cout << "Received pong packet with value " << pongPacket.getValue ( ) << "!" << std::endl ;
	}
	else if ( operationCode == PhatChat::OperationCode::REQUEST_USERNAME )
	{
        PhatChat::RequestUsernamePacket requestUsernamePacket = PhatChat::RequestUsernamePacket::decode ( packet ) ;
        this->setUsername ( requestUsernamePacket.getUsername ( ) ) ;
	}
	else if ( operationCode == PhatChat::OperationCode::MESSAGE )
	{
        PhatChat::MessagePacket messagePacket = PhatChat::MessagePacket::decode ( packet ) ;
        
        std::string username = this->username.empty ( ) ? messagePacket.getUsername ( ) : this->username ;
        std::cout << "Received message from " << username << " saying \"" << messagePacket.getMessage ( ) << "\"!" << std::endl ;
        
        if ( * messagePacket.getMessage ( ).begin ( ) == '/' )
        	this->handleCommand ( messagePacket.getMessage ( ) ) ;
        else
		{
        	messagePacket.setUsername ( username ) ;
        	
		    for ( auto client : this->clientManager )
		    {
		        packet = messagePacket.encode ( ) ;
		        client->getSocket ( ).send ( packet ) ;
		    }
		 }
	}
	else
		std::cout << "Operation code is unknown! Skip " << packet.getDataSize ( ) << " bytes." << std::endl ;
}
コード例 #4
0
SocketStatus NetworkManager::send(sf::Packet& PacketToSend)
{
    // Get the data to send from the packet
    std::size_t DataSize = 0;
    const char* Data = PacketToSend.OnSend(DataSize);

    // Send the packet size
    sf::Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize));
	send<sf::Uint32>(PacketSize);

    // Send the packet data
    if (PacketSize > 0)
		return Send(Data,DataSize);
    else
        return Done;
}
コード例 #5
0
bool MasterEntityList::getChangedEntities(sf::Packet& packet)
{
    bool anyChanged = false;
    packet << Packet::EntityUpdate;
    // Get deleted entities
    if (!deletedEnts.empty())
    {
        std::cout << "Deleted entity IDs: ";
        for (auto& entId: deletedEnts)
        {
            std::cout << entId << " ";
            packet << entId << -1;
            anyChanged = true;
        }
        std::cout << std::endl;
        deletedEnts.clear();
    }
    // Get changed entities
    if (entCount > 0)
    {
        for (auto& ent: ents)
        {
            if (ent != nullptr && ent->hasChanged())
            {
                ent->getData(packet);
                ent->setChanged(false);
                anyChanged = true;
            }
            if (packet.getDataSize() >= sf::UdpSocket::MaxDatagramSize - 256)
                break;
        }
        /*if (anyChanged)
            cout << "getChangedEntities()\n";*/
        return anyChanged;
    }
    else
        return false;
}
コード例 #6
0
ファイル: Connection.cpp プロジェクト: Strikerklm96/Beta
void Connection::prepSend(Protocol proto, const sf::Packet& rData, sf::Packet& data)
{
    data << static_cast<int32_t>(proto);
    data << ++m_lastSendRecieve[proto].first;
    data.append(rData.getData(), rData.getDataSize());
}
コード例 #7
0
void PacketBroker::receive(sf::Packet& packet, Protocol protocol)
{
	using namespace sf;

	if (protocol == Protocol::TCP)
	{
		if (Globals::Networking->ReceiveSafe(packet) != Socket::Status::Done)
			return;
	}
	else
	{
		PacketHandler::RemoteAddress remoteAddress;
		if (Globals::Networking->ReceiveFast(packet, remoteAddress) != Socket::Status::Done)
			return;

		if (!Globals::Networking->isConnectedAddress(remoteAddress))
			return;

		ushort sequence = 0;
		packet >> sequence;

		// TODO: Rejection threshold
		if (sequence == 0 || sequence <= lastSequence)
		{
			PrintDebug(">> Received out of order packet. Rejecting.");
			lastSequence = sequence % USHRT_MAX;
			return;
		}

		lastSequence = sequence % USHRT_MAX;
	}

	PlayerNumber pnum = -1;

	if (netStat)
		addBytesReceived(packet.getDataSize());

	while (!packet.endOfPacket())
	{
		MessageID newType;
		packet >> newType;

		// TODO: Re-implement packet loop failsafe using read offset.

		switch (newType)
		{
			case MessageID::None:
				PrintDebug("\a>> Reached end of packet.");
				break;

			case MessageID::Count:
				PrintDebug(">> Received message count?! Malformed packet warning!");
				break;

			case MessageID::N_Disconnect:
				PrintDebug(">> Received disconnect request from client.");
				Globals::Networking->Disconnect();
				break;

			case MessageID::N_Ready:
			{
				MessageID waitID; packet >> waitID;
				auto it = waitRequests.find(waitID);

				if (it != waitRequests.end())
				{
					it->second = true;
				}
				else
				{
					waitRequests[waitID] = true;
				}

				break;
			}

			case MessageID::N_PlayerNumber:
				packet >> pnum;
				break;

				// TODO: verification that this is from the host
			case MessageID::N_SetPlayer:
			{
				PlayerNumber changed;
				packet >> changed;
				SetPlayerNumber(changed);
				break;
			}

			case MessageID::S_KeepAlive:
				receivedKeepalive = Millisecs();
				packet.seekRead(sizeof(ushort), SEEK_CUR);
				break;

			default:
			{
				if (newType < MessageID::N_END)
				{
					packet.clear();
					break;
				}

				ushort length;
				packet >> length;

				AddTypeReceived(newType, length, protocol == Protocol::TCP);

				if (pnum >= 0)
				{
					if (receiveSystem(newType, pnum, packet))
						break;

					if (pnum != playerNum)
					{
						if (!writePlayer)
							inPlayer.Copy(Player[pnum]);

						if (receivePlayer(newType, pnum, packet))
						{
							if (GameState >= GameState::Ingame)
							{
								writePlayer = false;
								PlayerObject::WritePlayer(Player[pnum], &inPlayer);
							}

							break;
						}
					}

					if (receiveMenu(newType, pnum, packet))
						break;
				}

				if (runMessageHandler(newType, pnum, packet))
					break;

				PrintDebug("\t\t[P%d] Skipping %d bytes for id %02d", pnum, length, newType);
				packet.seekRead(length, SEEK_CUR);

				break;
			}
		}
	}
}
コード例 #8
0
void NetPlayClient::Send(sf::Packet& packet)
{
	ENetPacket* epac = enet_packet_create(packet.getData(), packet.getDataSize(), ENET_PACKET_FLAG_RELIABLE);
	enet_peer_send(m_server, 0, epac);
}
コード例 #9
0
ファイル: Manager.cpp プロジェクト: antoinusitos/Network
		void Manager::send(const Client &client, const sf::Packet &packet)
		{
			assert(client.getPeer());
			ENetPacket *netPacket = enet_packet_create(packet.getData(), packet.getDataSize(), 0);
			enet_peer_send(client.getPeer(), 0, netPacket);
		}
コード例 #10
0
ファイル: Manager.cpp プロジェクト: antoinusitos/Network
		void Manager::broadcast(const sf::Packet &packet)
		{
			assert(_host);
			ENetPacket *netPacket = enet_packet_create(packet.getData(), packet.getDataSize(), 0);
			enet_host_broadcast(_host, 0, netPacket);
		}
コード例 #11
0
ファイル: NetPlayServer.cpp プロジェクト: MerryMage/dolphin
// called from ---NETPLAY--- thread
unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
{
  MessageId mid;
  packet >> mid;

  INFO_LOG(NETPLAY, "Got client message: %x", mid);

  // don't need lock because this is the only thread that modifies the players
  // only need locks for writes to m_players in this thread

  switch (mid)
  {
  case NP_MSG_CHAT_MESSAGE:
  {
    std::string msg;
    packet >> msg;

    // send msg to other clients
    sf::Packet spac;
    spac << (MessageId)NP_MSG_CHAT_MESSAGE;
    spac << player.pid;
    spac << msg;

    SendToClients(spac, player.pid);
  }
  break;

  case NP_MSG_PAD_DATA:
  {
    // if this is pad data from the last game still being received, ignore it
    if (player.current_game != m_current_game)
      break;

    sf::Packet spac;
    spac << static_cast<MessageId>(NP_MSG_PAD_DATA);

    while (!packet.endOfPacket())
    {
      PadMapping map;
      packet >> map;

      // If the data is not from the correct player,
      // then disconnect them.
      if (m_pad_map.at(map) != player.pid)
      {
        return 1;
      }

      GCPadStatus pad;
      packet >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >>
          pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected;

      if (m_host_input_authority)
      {
        m_last_pad_status[map] = pad;

        if (!m_first_pad_status_received[map])
        {
          m_first_pad_status_received[map] = true;
          SendFirstReceivedToHost(map, true);
        }
      }
      else
      {
        spac << map << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY
             << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight
             << pad.isConnected;
      }
    }

    if (!m_host_input_authority)
      SendToClients(spac, player.pid);
  }
  break;

  case NP_MSG_PAD_HOST_POLL:
  {
    PadMapping pad_num;
    packet >> pad_num;

    sf::Packet spac;
    spac << static_cast<MessageId>(NP_MSG_PAD_DATA);

    if (pad_num < 0)
    {
      for (size_t i = 0; i < m_pad_map.size(); i++)
      {
        if (m_pad_map[i] == -1)
          continue;

        const GCPadStatus& pad = m_last_pad_status[i];
        spac << static_cast<PadMapping>(i) << pad.button << pad.analogA << pad.analogB << pad.stickX
             << pad.stickY << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight
             << pad.isConnected;
      }
    }
    else if (m_pad_map.at(pad_num) != -1)
    {
      const GCPadStatus& pad = m_last_pad_status[pad_num];
      spac << pad_num << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY
           << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight
           << pad.isConnected;
    }

    SendToClients(spac);
  }
  break;

  case NP_MSG_WIIMOTE_DATA:
  {
    // if this is Wiimote data from the last game still being received, ignore it
    if (player.current_game != m_current_game)
      break;

    PadMapping map = 0;
    u8 size;
    packet >> map >> size;
    std::vector<u8> data(size);
    for (size_t i = 0; i < data.size(); ++i)
      packet >> data[i];

    // If the data is not from the correct player,
    // then disconnect them.
    if (m_wiimote_map.at(map) != player.pid)
    {
      return 1;
    }

    // relay to clients
    sf::Packet spac;
    spac << (MessageId)NP_MSG_WIIMOTE_DATA;
    spac << map;
    spac << size;
    for (const u8& byte : data)
      spac << byte;

    SendToClients(spac, player.pid);
  }
  break;

  case NP_MSG_PONG:
  {
    const u32 ping = (u32)m_ping_timer.GetTimeElapsed();
    u32 ping_key = 0;
    packet >> ping_key;

    if (m_ping_key == ping_key)
    {
      player.ping = ping;
    }

    sf::Packet spac;
    spac << (MessageId)NP_MSG_PLAYER_PING_DATA;
    spac << player.pid;
    spac << player.ping;

    SendToClients(spac);
  }
  break;

  case NP_MSG_START_GAME:
  {
    packet >> player.current_game;
  }
  break;

  case NP_MSG_STOP_GAME:
  {
    if (!m_is_running)
      break;

    m_is_running = false;

    // tell clients to stop game
    sf::Packet spac;
    spac << (MessageId)NP_MSG_STOP_GAME;

    std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
    SendToClients(spac);
  }
  break;

  case NP_MSG_GAME_STATUS:
  {
    u32 status;
    packet >> status;

    m_players[player.pid].game_status = static_cast<PlayerGameStatus>(status);

    // send msg to other clients
    sf::Packet spac;
    spac << static_cast<MessageId>(NP_MSG_GAME_STATUS);
    spac << player.pid;
    spac << status;

    SendToClients(spac);
  }
  break;

  case NP_MSG_IPL_STATUS:
  {
    bool status;
    packet >> status;

    m_players[player.pid].has_ipl_dump = status;
  }
  break;

  case NP_MSG_TIMEBASE:
  {
    u64 timebase = Common::PacketReadU64(packet);
    u32 frame;
    packet >> frame;

    if (m_desync_detected)
      break;

    std::vector<std::pair<PlayerId, u64>>& timebases = m_timebase_by_frame[frame];
    timebases.emplace_back(player.pid, timebase);
    if (timebases.size() >= m_players.size())
    {
      // we have all records for this frame

      if (!std::all_of(timebases.begin(), timebases.end(), [&](std::pair<PlayerId, u64> pair) {
            return pair.second == timebases[0].second;
          }))
      {
        int pid_to_blame = -1;
        for (auto pair : timebases)
        {
          if (std::all_of(timebases.begin(), timebases.end(), [&](std::pair<PlayerId, u64> other) {
                return other.first == pair.first || other.second != pair.second;
              }))
          {
            // we are the only outlier
            pid_to_blame = pair.first;
            break;
          }
        }

        sf::Packet spac;
        spac << (MessageId)NP_MSG_DESYNC_DETECTED;
        spac << pid_to_blame;
        spac << frame;
        SendToClients(spac);

        m_desync_detected = true;
      }
      m_timebase_by_frame.erase(frame);
    }
  }
  break;

  case NP_MSG_MD5_PROGRESS:
  {
    int progress;
    packet >> progress;

    sf::Packet spac;
    spac << static_cast<MessageId>(NP_MSG_MD5_PROGRESS);
    spac << player.pid;
    spac << progress;

    SendToClients(spac);
  }
  break;

  case NP_MSG_MD5_RESULT:
  {
    std::string result;
    packet >> result;

    sf::Packet spac;
    spac << static_cast<MessageId>(NP_MSG_MD5_RESULT);
    spac << player.pid;
    spac << result;

    SendToClients(spac);
  }
  break;

  case NP_MSG_MD5_ERROR:
  {
    std::string error;
    packet >> error;

    sf::Packet spac;
    spac << static_cast<MessageId>(NP_MSG_MD5_ERROR);
    spac << player.pid;
    spac << error;

    SendToClients(spac);
  }
  break;

  case NP_MSG_SYNC_SAVE_DATA:
  {
    MessageId sub_id;
    packet >> sub_id;

    switch (sub_id)
    {
    case SYNC_SAVE_DATA_SUCCESS:
    {
      if (m_start_pending)
      {
        m_save_data_synced_players++;
        if (m_save_data_synced_players >= m_players.size() - 1)
        {
          m_dialog->AppendChat(GetStringT("All players synchronized."));
          StartGame();
        }
      }
    }
    break;

    case SYNC_SAVE_DATA_FAILURE:
    {
      m_dialog->AppendChat(
          StringFromFormat(GetStringT("%s failed to synchronize.").c_str(), player.name.c_str()));
      m_dialog->OnSaveDataSyncFailure();
      m_start_pending = false;
    }
    break;

    default:
      PanicAlertT(
          "Unknown SYNC_SAVE_DATA message with id:%d received from player:%d Kicking player!",
          sub_id, player.pid);
      return 1;
    }
  }
  break;

  default:
    PanicAlertT("Unknown message with id:%d received from player:%d Kicking player!", mid,
                player.pid);
    // unknown message, kick the client
    return 1;
  }

  return 0;
}
コード例 #12
0
ファイル: NetPlayServer.cpp プロジェクト: MerryMage/dolphin
void NetPlayServer::Send(ENetPeer* socket, const sf::Packet& packet)
{
  ENetPacket* epac =
      enet_packet_create(packet.getData(), packet.getDataSize(), ENET_PACKET_FLAG_RELIABLE);
  enet_peer_send(socket, 0, epac);
}