Example #1
0
static int
enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
    ENetPeer * currentPeer = host -> lastServicedPeer;
    ENetChannel * channel;

    do
    {
       ++ currentPeer;
       
       if (currentPeer >= & host -> peers [host -> peerCount])
         currentPeer = host -> peers;

       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
         continue;

       if (currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
       {
           host -> recalculateBandwidthLimits = 1;

           event -> type = ENET_EVENT_TYPE_DISCONNECT;
           event -> peer = currentPeer;

           enet_peer_reset (currentPeer);

           host -> lastServicedPeer = currentPeer;

           return 1;
       }

       for (channel = currentPeer -> channels;
            channel < & currentPeer -> channels [currentPeer -> channelCount];
            ++ channel)
       {
           if (enet_list_empty (& channel -> incomingReliableCommands) &&
               enet_list_empty (& channel -> incomingUnreliableCommands))
             continue;

           event -> packet = enet_peer_receive (currentPeer, (enet_uint8)(channel - currentPeer -> channels));
           if (event -> packet == NULL)
             continue;
             
           
           event -> type = ENET_EVENT_TYPE_RECEIVE;
           event -> peer = currentPeer;
           event -> channelID = (enet_uint8) (channel - currentPeer -> channels);

           host -> lastServicedPeer = currentPeer;

           return 1;
       }
    } while (currentPeer != host -> lastServicedPeer);

    return 0;
}
Example #2
0
// called from ---NETPLAY--- thread
unsigned int NetPlayServer::OnConnect(ENetPeer* socket)
{
  sf::Packet rpac;
  ENetPacket* epack;
  do
  {
    epack = enet_peer_receive(socket, nullptr);
  } while (epack == nullptr);
  rpac.append(epack->data, epack->dataLength);

  // give new client first available id
  PlayerId pid = 1;
  for (auto i = m_players.begin(); i != m_players.end(); ++i)
  {
    if (i->second.pid == pid)
    {
      pid++;
      i = m_players.begin();
    }
  }
  socket->data = new PlayerId(pid);

  std::string npver;
  rpac >> npver;
  // Dolphin netplay version
  if (npver != Common::scm_rev_git_str)
    return CON_ERR_VERSION_MISMATCH;

  // game is currently running
  if (m_is_running)
    return CON_ERR_GAME_RUNNING;

  // too many players
  if (m_players.size() >= 255)
    return CON_ERR_SERVER_FULL;

  // cause pings to be updated
  m_update_pings = true;

  Client player;
  player.pid = pid;
  player.socket = socket;

  rpac >> player.revision;
  rpac >> player.name;

  enet_packet_destroy(epack);
  // try to automatically assign new user a pad
  for (PadMapping& mapping : m_pad_map)
  {
    if (mapping == -1)
    {
      mapping = player.pid;
      break;
    }
  }

  // send join message to already connected clients
  sf::Packet spac;
  spac << static_cast<MessageId>(NP_MSG_PLAYER_JOIN);
  spac << player.pid << player.name << player.revision;
  SendToClients(spac);

  // send new client success message with their id
  spac.clear();
  spac << static_cast<MessageId>(0);
  spac << player.pid;
  Send(player.socket, spac);

  // send new client the selected game
  if (m_selected_game != "")
  {
    spac.clear();
    spac << static_cast<MessageId>(NP_MSG_CHANGE_GAME);
    spac << m_selected_game;
    Send(player.socket, spac);
  }

  if (!m_host_input_authority)
  {
    // send the pad buffer value
    spac.clear();
    spac << static_cast<MessageId>(NP_MSG_PAD_BUFFER);
    spac << static_cast<u32>(m_target_buffer_size);
    Send(player.socket, spac);
  }

  // send input authority state
  spac.clear();
  spac << static_cast<MessageId>(NP_MSG_HOST_INPUT_AUTHORITY);
  spac << m_host_input_authority;
  Send(player.socket, spac);

  // sync GC SRAM with new client
  if (!g_SRAM_netplay_initialized)
  {
    SConfig::GetInstance().m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
    InitSRAM();
    g_SRAM_netplay_initialized = true;
  }
  spac.clear();
  spac << static_cast<MessageId>(NP_MSG_SYNC_GC_SRAM);
  for (size_t i = 0; i < sizeof(g_SRAM) - offsetof(Sram, settings); ++i)
  {
    spac << g_SRAM[offsetof(Sram, settings) + i];
  }
  Send(player.socket, spac);

  // sync values with new client
  for (const auto& p : m_players)
  {
    spac.clear();
    spac << static_cast<MessageId>(NP_MSG_PLAYER_JOIN);
    spac << p.second.pid << p.second.name << p.second.revision;
    Send(player.socket, spac);

    spac.clear();
    spac << static_cast<MessageId>(NP_MSG_GAME_STATUS);
    spac << p.second.pid << static_cast<u32>(p.second.game_status);
    Send(player.socket, spac);
  }

  if (Config::Get(Config::NETPLAY_ENABLE_QOS))
    player.qos_session = Common::QoSSession(player.socket);

  // add client to the player list
  {
    std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
    m_players.emplace(*(PlayerId*)player.socket->data, std::move(player));
    UpdatePadMapping();  // sync pad mappings with everyone
    UpdateWiimoteMapping();
  }

  return 0;
}