mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-08-16 08:16:20 +00:00
Server info (#161)
Adds an `I` packet to the core handler, which allows the mod to use the newly added [information packet ](https://github.com/BeamMP/BeamMP-Server/pull/382) in the server. Usage: Mod sends `I0.0.0.0:0000` and the launcher will send either `I0.0.0.0:0000;` back if something went wrong, or `I0.0.0.0:0000;{Server information JSON}` if it succeeded. --- By creating this pull request, I understand that code that is AI generated or otherwise automatically generated may be rejected without further discussion. I declare that I fully understand all code I pushed into this PR, and wrote all this code myself and own the rights to this code.
This commit is contained in:
commit
e5e40e186b
@ -13,6 +13,7 @@
|
|||||||
#include <bits/types/siginfo_t.h>
|
#include <bits/types/siginfo_t.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <sys/ucontext.h>
|
#include <sys/ucontext.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void NetReset();
|
void NetReset();
|
||||||
|
@ -89,6 +89,98 @@ void StartSync(const std::string& Data) {
|
|||||||
info("Connecting to server");
|
info("Connecting to server");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetServerInfo(std::string Data) {
|
||||||
|
debug("Fetching server info of " + Data.substr(1));
|
||||||
|
|
||||||
|
std::string IP = GetAddr(Data.substr(1, Data.find(':') - 1));
|
||||||
|
if (IP.find('.') == -1) {
|
||||||
|
if (IP == "DNS")
|
||||||
|
warn("Connection Failed! (DNS Lookup Failed) for " + Data);
|
||||||
|
else
|
||||||
|
warn("Connection Failed! (WSA failed to start) for " + Data);
|
||||||
|
CoreSend("I" + Data + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET ISock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
SOCKADDR_IN ServerAddr;
|
||||||
|
if (ISock < 1) {
|
||||||
|
debug("Socket creation failed with error: " + std::to_string(WSAGetLastError()));
|
||||||
|
KillSocket(ISock);
|
||||||
|
CoreSend("I" + Data + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ServerAddr.sin_family = AF_INET;
|
||||||
|
|
||||||
|
int port = std::stoi(Data.substr(Data.find(':') + 1));
|
||||||
|
|
||||||
|
if (port < 1 || port > 65535) {
|
||||||
|
debug("Invalid port number: " + std::to_string(port));
|
||||||
|
KillSocket(ISock);
|
||||||
|
CoreSend("I" + Data + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerAddr.sin_port = htons(port);
|
||||||
|
inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr);
|
||||||
|
if (connect(ISock, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)) != 0) {
|
||||||
|
debug("Connection to server failed with error: " + std::to_string(WSAGetLastError()));
|
||||||
|
KillSocket(ISock);
|
||||||
|
CoreSend("I" + Data + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char Code[1] = { 'I' };
|
||||||
|
if (send(ISock, Code, 1, 0) != 1) {
|
||||||
|
debug("Sending data to server failed with error: " + std::to_string(WSAGetLastError()));
|
||||||
|
KillSocket(ISock);
|
||||||
|
CoreSend("I" + Data + ";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string buffer = ([&]() -> std::string {
|
||||||
|
int32_t Header;
|
||||||
|
std::vector<char> data(sizeof(Header));
|
||||||
|
int32_t Temp = recv(ISock, data.data(), sizeof(Header), MSG_WAITALL);
|
||||||
|
|
||||||
|
auto checkBytes = ([&](const int32_t bytes) -> bool {
|
||||||
|
if (bytes == 0) {
|
||||||
|
return false;
|
||||||
|
} else if (bytes < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!checkBytes(Temp)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
memcpy(&Header, data.data(), sizeof(Header));
|
||||||
|
|
||||||
|
if (!checkBytes(Temp)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
data.resize(Header, 0);
|
||||||
|
Temp = recv(ISock, data.data(), Header, MSG_WAITALL);
|
||||||
|
if (!checkBytes(Temp)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return std::string(data.data(), Header);
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (!buffer.empty()) {
|
||||||
|
debug("Server Info: " + buffer);
|
||||||
|
|
||||||
|
CoreSend("I" + Data + ";" + buffer);
|
||||||
|
} else {
|
||||||
|
debug("Receiving data from server failed with error: " + std::to_string(WSAGetLastError()));
|
||||||
|
debug("Failed to receive server info from " + Data);
|
||||||
|
CoreSend("I" + Data + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
KillSocket(ISock);
|
||||||
|
}
|
||||||
std::mutex sendMutex;
|
std::mutex sendMutex;
|
||||||
|
|
||||||
void CoreSend(std::string data) {
|
void CoreSend(std::string data) {
|
||||||
@ -235,6 +327,12 @@ void Parse(std::string Data, SOCKET CSocket) {
|
|||||||
|
|
||||||
Data.clear();
|
Data.clear();
|
||||||
break;
|
break;
|
||||||
|
case 'I': {
|
||||||
|
auto future = std::async(std::launch::async, [data = std::move(Data)]() {
|
||||||
|
GetServerInfo(data);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
Data.clear();
|
Data.clear();
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user