HTTP Resolver (Server Data)
TCP server on port 80 returning server connection data to clients
Overview
The HTTP resolver is a separate TCP server that runs on port 80. It responds to client requests with server connection information (IP, port, type) in the format expected by the Growtopia client (server_data.php format).
Thread: Detached std::thread (commented out in main, but can be enabled)
Implementation
static void resolver_loop(int game_port) {
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) return;
SOCKET srv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (srv == INVALID_SOCKET) return;
int yes = 1;
setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(yes));
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(80);
if (::bind(srv, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
cout << "[Resolver] Failed to bind port 80 (needs Administrator)" << endl;
closesocket(srv);
return;
}
listen(srv, SOMAXCONN);
// Response format (pipe-delimited)
string response = "server|127.0.0.1\n"
+ "port|" + to_string(game_port) + "\n"
+ "type|1\n"
+ "type2|1\n"
+ "beta_server|127.0.0.1\n"
+ "beta_port|" + to_string(game_port) + "\n"
+ "beta_type|1\n"
+ "meta|localhost\n"
+ "RTENDMARKERBS1001";
cout << "[Resolver] Listening on port 80 (server_data.php -> 127.0.0.1:" << game_port << ")" << endl;
while (true) {
SOCKET c = accept(srv, nullptr, nullptr);
if (c == INVALID_SOCKET) continue;
char buf[1024] = { 0 };
recv(c, buf, sizeof(buf), 0);
string http = "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/plain\r\n"
+ "Content-Length: " + to_string(response.size()) + "\r\n"
+ "Connection: close\r\n\r\n"
+ response;
send(c, http.c_str(), (int)http.size(), 0);
closesocket(c);
}
}Response Format
| Field | Example Value | Description |
|---|---|---|
| server | 127.0.0.1 | Main game server IP |
| port | 53181 | Game UDP port |
| type | 1 | Server type (1=main) |
| type2 | 1 | Secondary type |
| beta_server | 127.0.0.1 | Beta server IP |
| beta_port | 53181 | Beta server port |
| beta_type | 1 | Beta server type |
| meta | localhost | Metadata identifier |
| RTENDMARKERBS1001 | (fixed) | End-of-response marker |
Client Request Flow
- Game client starts, resolves server domain
- Client sends HTTP GET to
http://server_domain/(port 80) - Resolver returns pipe-delimited response above
- Client parses response, extracts
serverandport - Client initiates ENet connection to game server UDP port
Requirements & Caveats
Administrator Required
Binding to port 80 requires elevated privileges on Windows. Run server as Administrator.
HTTPS Not Supported
Resolver uses plain HTTP. Modern clients may require HTTPS or certificate pinning.
Thread Safety
Resolver runs in detached thread. Uses read-only access to server_port.
Enabling the Resolver
The resolver thread is currently commented out in main():
// std::thread resolver(resolver_loop, server_port);
// resolver.detach();Uncomment and ensure the server is run as Administrator to enable.
HTTP Client Utility
The codebase includes a full HTTP client implementation used for outbound requests (e.g., crypto price fetching). Features:
- Sync HTTP/1.1 client with chunked encoding support
- Timeout handling, redirect following
- Cross-platform (Windows/Linux/macOS)
- Used in crypto price updates