Bläddra i källkod

abort discovery

Laserlicht 1 månad sedan
förälder
incheckning
4c20e86eca

+ 4 - 1
client/mainmenu/CMainMenu.cpp

@@ -565,7 +565,7 @@ JoinScreen::JoinScreen(ESelectionScreen ScreenType, std::vector<std::string> Pla
 		CMainMenu::openLobby(savedScreenType, false, savedPlayerNames, ELoadMode::MULTI, false);
 	}, EShortcut::MAIN_MENU_JOIN_GAME);
 
-	ServerDiscovery::discoverAsync(
+	serverDiscovery = std::make_shared<ServerDiscovery>(
 		GAME->server().getNetworkHandler().getContext(),
 		[this](const DiscoveredServer & server)
 		{
@@ -586,10 +586,13 @@ JoinScreen::JoinScreen(ESelectionScreen ScreenType, std::vector<std::string> Pla
 			redraw();
 		}
 	);
+	serverDiscovery->start();
 
 	buttonCancel = std::make_shared<CButton>(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), LIBRARY->generaltexth->zelp[288], [this](){ close();}, EShortcut::GLOBAL_CANCEL);
 }
 
+JoinScreen::~JoinScreen() = default;
+
 CMultiPlayers::CMultiPlayers(const std::vector<std::string>& playerNames, ESelectionScreen ScreenType, bool Host, ELoadMode LoadMode, EShortcut shortcut)
 	: loadMode(LoadMode), screenType(ScreenType), host(Host)
 {

+ 3 - 0
client/mainmenu/CMainMenu.h

@@ -16,6 +16,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CampaignState;
+class ServerDiscovery;
 
 VCMI_LIB_NAMESPACE_END
 
@@ -118,8 +119,10 @@ public:
 	std::shared_ptr<CGStatusBar> statusBar;
 	std::vector<std::shared_ptr<CLabel>> labelsJoin;
 	std::vector<std::shared_ptr<CButton>> buttonsJoin;
+	std::shared_ptr<ServerDiscovery> serverDiscovery;
 
 	JoinScreen(ESelectionScreen ScreenType, std::vector<std::string> playerNames);
+	~JoinScreen();
 };
 
 /// Hot seat player window

+ 29 - 5
lib/network/NetworkDiscovery.cpp

@@ -14,20 +14,41 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-void ServerDiscovery::discoverAsync(NetworkContext & context, std::function<void(const DiscoveredServer &)> callback)
+ServerDiscovery::ServerDiscovery(NetworkContext & context, std::function<void(const DiscoveredServer &)> callback)
+	: context(context), callback(std::move(callback))
 {
-	auto socket = std::make_shared<boost::asio::ip::udp::socket>(context);
+}
+
+ServerDiscovery::~ServerDiscovery()
+{
+	abort();
+}
+
+void ServerDiscovery::abort()
+{
+	if(socket)
+	{
+		boost::system::error_code ec;
+		socket->close(ec);
+		socket.reset();
+	}
+}
+
+void ServerDiscovery::start()
+{
+	socket = std::make_shared<boost::asio::ip::udp::socket>(context);
 	socket->open(boost::asio::ip::udp::v4());
 	socket->set_option(boost::asio::socket_base::broadcast(true));
 
 	std::string message = "VCMI_DISCOVERY";
 	boost::asio::ip::udp::endpoint broadcastEndpoint(boost::asio::ip::address_v4::broadcast(), 3030);
 	socket->async_send_to(boost::asio::buffer(message), broadcastEndpoint,
-		[socket, callback](const boost::system::error_code& ec, std::size_t)
+		[this, socket = this->socket](const boost::system::error_code& ec, std::size_t)
 		{
 			if(ec)
 			{
-				logGlobal->error("Discovery send error: %s", ec.message());
+				if(ec != boost::asio::error::operation_aborted)
+					logGlobal->error("Discovery send error: %s", ec.message());
 				return;
 			}
 
@@ -36,8 +57,11 @@ void ServerDiscovery::discoverAsync(NetworkContext & context, std::function<void
 			auto timer = std::make_shared<boost::asio::steady_timer>(socket->get_executor(), std::chrono::milliseconds(5000));
 			
 			std::function<void(const boost::system::error_code&, std::size_t)> receiveHandler;
-			receiveHandler = [socket, recvBuf, senderEndpoint, timer, callback, &receiveHandler](const boost::system::error_code& ec, std::size_t len)
+			receiveHandler = [this, socket, recvBuf, senderEndpoint, timer, &receiveHandler](const boost::system::error_code& ec, std::size_t len)
 			{
+				if(ec == boost::asio::error::operation_aborted)
+					return;
+				
 				if(!ec && len > 0)
 				{
 					std::string resp(recvBuf->data(), recvBuf->data() + len);

+ 9 - 1
lib/network/NetworkDiscovery.h

@@ -23,8 +23,16 @@ struct DLL_LINKAGE DiscoveredServer
 class DLL_LINKAGE ServerDiscovery
 {
 public:
-	static void discoverAsync(NetworkContext & context, std::function<void(const DiscoveredServer &)> callback);
+	ServerDiscovery(NetworkContext & context, std::function<void(const DiscoveredServer &)> callback);
+	~ServerDiscovery();
+	void start();
+	void abort();
 	static std::vector<std::string> ipAddresses();
+
+private:
+	NetworkContext & context;
+	std::function<void(const DiscoveredServer &)> callback;
+	std::shared_ptr<boost::asio::ip::udp::socket> socket;
 };
 
 class DLL_LINKAGE ServerDiscoveryListener