[World] Check if port in use to avoid double booting mistakes (#4740)

* Stuff

* Potentially fix aura crash

* Reload crash fix

* Revert "Reload crash fix"

This reverts commit 96e1e76306059fc2a624e0152eca4beaee49a0f8.

* Fix

* Update entity.cpp

* Update dbcore.cpp

* [World] Check if port in use to avoid double booting mistakes

* Revert "Stuff"

This reverts commit 2162c00eddfd13c7ff9fbe53cada1ea36373880c.

* Revert "Potentially fix aura crash"

This reverts commit 7c242723f40a0d013371c36e205a9917849ee862.

* Revert "Fix"

This reverts commit 8419e284d48bac823c861c480719eb3d3b8290a9.

* Revert "Update entity.cpp"

This reverts commit 8a1f4545a4e1c96a848866fb5b6185c66db09097.

* Revert "Update dbcore.cpp"

This reverts commit f0278d95910ccf9e1667eb0e1a0f2608aa7b6058.
This commit is contained in:
Chris Miles 2025-03-03 00:04:03 -06:00 committed by GitHub
parent 8b13434197
commit de4226fdc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 85 additions and 0 deletions

View File

@ -259,3 +259,76 @@ bool IpUtil::IsIPAddress(const std::string &ip_address)
} }
#include <iostream>
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib") // Link against Winsock library
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
#include <iostream>
#include <string>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h> // For inet_pton
#pragma comment(lib, "ws2_32.lib") // Link against Winsock library
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> // For inet_pton
#include <unistd.h>
#endif
bool IpUtil::IsPortInUse(const std::string& ip, int port) {
bool in_use = false;
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed\n";
return true; // Assume in use on failure
}
#endif
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
#ifdef _WIN32
WSACleanup();
#endif
return true; // Assume in use on failure
}
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
// Convert IP address from string to binary format
if (inet_pton(AF_INET, ip.c_str(), &addr.sin_addr) <= 0) {
std::cerr << "Invalid IP address format: " << ip << std::endl;
#ifdef _WIN32
closesocket(sock);
WSACleanup();
#else
close(sock);
#endif
return true; // Assume in use on failure
}
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
in_use = true; // Bind failed, port is in use
}
#ifdef _WIN32
closesocket(sock);
WSACleanup();
#else
close(sock);
#endif
return in_use;
}

View File

@ -37,6 +37,7 @@ public:
int port int port
); );
static bool IsIPAddress(const std::string &ip_address); static bool IsIPAddress(const std::string &ip_address);
static bool IsPortInUse(const std::string& ip, int port);
}; };

View File

@ -89,6 +89,7 @@
#include "../common/events/player_event_logs.h" #include "../common/events/player_event_logs.h"
#include "../common/skill_caps.h" #include "../common/skill_caps.h"
#include "../common/repositories/character_parcels_repository.h" #include "../common/repositories/character_parcels_repository.h"
#include "../common/ip_util.h"
SkillCaps skill_caps; SkillCaps skill_caps;
ZoneStore zone_store; ZoneStore zone_store;
@ -188,6 +189,16 @@ int main(int argc, char **argv)
launcher_list.LoadList(); launcher_list.LoadList();
zoneserver_list.Init(); zoneserver_list.Init();
if (IpUtil::IsPortInUse(Config->WorldIP, Config->WorldTCPPort)) {
LogError("World port [{}] already in use", Config->WorldTCPPort);
return 1;
}
if (IpUtil::IsPortInUse(Config->TelnetIP, Config->TelnetTCPPort)) {
LogError("Telnet port [{}] already in use", Config->TelnetTCPPort);
return 1;
}
std::unique_ptr<EQ::Net::ConsoleServer> console; std::unique_ptr<EQ::Net::ConsoleServer> console;
if (Config->TelnetEnabled) { if (Config->TelnetEnabled) {
LogInfo("Console (TCP) listener started on [{}:{}]", Config->TelnetIP, Config->TelnetTCPPort); LogInfo("Console (TCP) listener started on [{}:{}]", Config->TelnetIP, Config->TelnetTCPPort);