void receive() { sf::Packet packet; sf::Socket::Status status = socket_.Receive(packet); if (status == sf::Socket::Done) { uint8 id; packet >> id; if (id >= N_NET_INSTRUCTIONS) { socket_.Close(); PyErr_SetString(PyExc_ValueError, "Received a network instruction over maximum"); throw_error_already_set(); } fcs[id](packet); }
// called from ---NETPLAY--- thread unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) { sf::Packet rpac; // TODO: make this not hang / check if good packet socket.Receive(rpac); std::string npver; rpac >> npver; // dolphin netplay version if (npver != NETPLAY_VERSION) 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.socket = socket; rpac >> player.revision; rpac >> player.name; // give new client first available id player.pid = (PlayerId)(m_players.size() + 1); // try to automatically assign new user a pad for (PadMapping& mapping : m_pad_map) { if (mapping == -1) { mapping = player.pid; break; } } { std::lock_guard<std::recursive_mutex> lks(m_crit.send); // send join message to already connected clients sf::Packet spac; spac << (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 << (MessageId)0; spac << player.pid; socket.Send(spac); // send new client the selected game if (m_selected_game != "") { spac.Clear(); spac << (MessageId)NP_MSG_CHANGE_GAME; spac << m_selected_game; socket.Send(spac); } // send the pad buffer value spac.Clear(); spac << (MessageId)NP_MSG_PAD_BUFFER; spac << (u32)m_target_buffer_size; socket.Send(spac); // sync values with new client for (const auto& p : m_players) { spac.Clear(); spac << (MessageId)NP_MSG_PLAYER_JOIN; spac << p.second.pid << p.second.name << p.second.revision; socket.Send(spac); } } // unlock send // add client to the player list { std::lock_guard<std::recursive_mutex> lkp(m_crit.players); m_players[socket] = player; std::lock_guard<std::recursive_mutex> lks(m_crit.send); UpdatePadMapping(); // sync pad mappings with everyone UpdateWiimoteMapping(); } // add client to selector/ used for receiving m_selector.Add(socket); return 0; }