mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-09 20:24:16 +00:00
cleanup and make the web routes cleaner
This commit is contained in:
@@ -9,8 +9,13 @@
|
||||
#include "dConfig.h"
|
||||
#include "PlayerContainer.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "JSONUtils.h"
|
||||
#include "eHTTPMethod.h"
|
||||
#include "eHTTPStatusCode.h"
|
||||
#include "magic_enum.hpp"
|
||||
#include "ChatPackets.h"
|
||||
|
||||
#include "json.hpp"
|
||||
#include "StringifiedEnum.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
@@ -22,75 +27,148 @@ namespace {
|
||||
const char* json_content_type = "Content-Type: application/json\r\n";
|
||||
}
|
||||
|
||||
struct HttpReply {
|
||||
uint32_t status = 404;
|
||||
struct HTTPReply {
|
||||
eHTTPStatusCode status = eHTTPStatusCode::NOT_FOUND;
|
||||
std::string message = "{\"error\":\"Not Found\"}";
|
||||
};
|
||||
|
||||
void HandleRequests(mg_connection* connection, int request, void* request_data) {
|
||||
if (request == MG_EV_HTTP_MSG) {
|
||||
HttpReply reply;
|
||||
const mg_http_message* const http_msg = static_cast<mg_http_message*>(request_data);
|
||||
if (!http_msg) {
|
||||
reply.status = 400;
|
||||
reply.message = "{\"error\":\"Invalid Request\"}";
|
||||
} else {
|
||||
// Handle Post requests
|
||||
if (mg_strcmp(http_msg->method, mg_str("POST")) == 0) {
|
||||
auto data = GeneralUtils::TryParse<json>(http_msg->body.buf);
|
||||
if (!data) {
|
||||
reply.status = 400;
|
||||
reply.message = "{\"error\":\"Invalid JSON\"}";
|
||||
} else if (mg_match(http_msg->uri, mg_str((root_path + "announce").c_str()), NULL)) {
|
||||
auto& jsonBuffer = data.value();
|
||||
// handle announcements
|
||||
bool CheckValidJSON(std::optional<json> data, HTTPReply& reply) {
|
||||
if (!data) {
|
||||
reply.status = eHTTPStatusCode::BAD_REQUEST;
|
||||
reply.message = "{\"error\":\"Invalid JSON\"}";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!jsonBuffer.contains("title")) {
|
||||
reply.status = 400;
|
||||
reply.message = "{\"error\":\"Missing paramater: title\"}";
|
||||
} else if (!jsonBuffer.contains("message")) {
|
||||
reply.status = 400;
|
||||
reply.message = "{\"error\":\"Missing paramater: message\"}";
|
||||
} else {
|
||||
std::string title = jsonBuffer["title"];
|
||||
std::string message = jsonBuffer["message"];
|
||||
void HandlePlayersRequest(HTTPReply& reply) {
|
||||
const json data = Game::playerContainer;
|
||||
reply.status = data.empty() ? eHTTPStatusCode::NO_CONTENT : eHTTPStatusCode::OK;
|
||||
reply.message = data.empty() ? "{\"error\":\"No Players Online\"}" : data.dump();
|
||||
}
|
||||
|
||||
// build and send the packet to all world servers
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, MessageType::Chat::GM_ANNOUNCE);
|
||||
bitStream.Write<uint32_t>(title.size());
|
||||
bitStream.Write(title);
|
||||
bitStream.Write<uint32_t>(message.size());
|
||||
bitStream.Write(message);
|
||||
SEND_PACKET_BROADCAST;
|
||||
void HandleTeamsRequest(HTTPReply& reply) {
|
||||
const json data = Game::playerContainer.GetTeamContainer();
|
||||
reply.status = data.empty() ? eHTTPStatusCode::NO_CONTENT : eHTTPStatusCode::OK;
|
||||
reply.message = data.empty() ? "{\"error\":\"No Teams Online\"}" : data.dump();
|
||||
}
|
||||
|
||||
reply.status = 200;
|
||||
reply.message = "{\"status\":\"Announcement Sent\"}";
|
||||
}
|
||||
}
|
||||
// Handle GET Requests
|
||||
} else if (mg_strcmp(http_msg->method, mg_str("GET")) == 0) {
|
||||
// Get All Online players
|
||||
if (mg_match(http_msg->uri, mg_str((root_path + "players").c_str()), NULL)) {
|
||||
const json data = Game::playerContainer;
|
||||
void HandleInvalidRoute(HTTPReply& reply) {
|
||||
reply.status = eHTTPStatusCode::NOT_FOUND;
|
||||
reply.message = "{\"error\":\"Invalid Route\"}";
|
||||
}
|
||||
|
||||
reply.status = data.empty() ? 204 : 200;
|
||||
reply.message = data.empty() ? "{\"error\":\"No Players Online\"}" : data.dump();
|
||||
} else if (mg_match(http_msg->uri, mg_str((root_path + "teams").c_str()), NULL)) {
|
||||
// Get Teams
|
||||
const json data = Game::playerContainer.GetTeamContainer();
|
||||
|
||||
reply.status = data.empty() ? 204 : 200;
|
||||
reply.message = data.empty() ? "{\"error\":\"No Teams Online\"}" : data.dump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("Replying with status %d: %s", reply.status, reply.message.c_str());
|
||||
mg_http_reply(connection, reply.status, json_content_type, reply.message.c_str());
|
||||
void HandleGET(HTTPReply& reply, const ChatWebAPI::eRoute& route , const std::string& body) {
|
||||
switch (route) {
|
||||
case ChatWebAPI::eRoute::PLAYERS:
|
||||
HandlePlayersRequest(reply);
|
||||
break;
|
||||
case ChatWebAPI::eRoute::TEAMS:
|
||||
HandleTeamsRequest(reply);
|
||||
break;
|
||||
case ChatWebAPI::eRoute::INVALID:
|
||||
default:
|
||||
HandleInvalidRoute(reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleAnnounceRequest(HTTPReply& reply, const std::optional<json>& data) {
|
||||
if (!CheckValidJSON(data, reply)) return;
|
||||
|
||||
const auto& good_data = data.value();
|
||||
auto check = JSONUtils::CheckRequiredData(good_data, { "title", "message" });
|
||||
if (!check.empty()) {
|
||||
reply.status = eHTTPStatusCode::BAD_REQUEST;
|
||||
reply.message = check;
|
||||
} else {
|
||||
|
||||
ChatPackets::Announcement announcement;
|
||||
announcement.title = good_data["title"];
|
||||
announcement.message = good_data["message"];
|
||||
announcement.Send();
|
||||
|
||||
reply.status = eHTTPStatusCode::OK;
|
||||
reply.message = "{\"status\":\"Announcement Sent\"}";
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePOST(HTTPReply& reply, const ChatWebAPI::eRoute& route , const std::string& body) {
|
||||
auto data = GeneralUtils::TryParse<json>(body);
|
||||
switch (route) {
|
||||
case ChatWebAPI::eRoute::ANNOUNCE:{
|
||||
HandleAnnounceRequest(reply, data.value());
|
||||
break;
|
||||
}
|
||||
case ChatWebAPI::eRoute::INVALID:
|
||||
default:
|
||||
HandleInvalidRoute(reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleHTTPMessage(mg_connection* connection, const mg_http_message* http_msg) {
|
||||
HTTPReply reply;
|
||||
|
||||
if (!http_msg) {
|
||||
reply.status = eHTTPStatusCode::BAD_REQUEST;
|
||||
reply.message = "{\"error\":\"Invalid Request\"}";
|
||||
} else {
|
||||
|
||||
// convert method from cstring to std string
|
||||
std::string method_string(http_msg->method.buf, http_msg->method.len);
|
||||
// get mehtod from mg to enum
|
||||
const eHTTPMethod method = magic_enum::enum_cast<eHTTPMethod>(method_string).value_or(eHTTPMethod::INVALID);
|
||||
|
||||
// convert uri from cstring to std string
|
||||
std::string uri(http_msg->uri.buf, http_msg->uri.len);
|
||||
// check for root path
|
||||
if (uri.find(root_path) == 0) {
|
||||
// remove root path from uri
|
||||
uri.erase(0, root_path.length());
|
||||
// convert uri to uppercase
|
||||
std::transform(uri.begin(), uri.end(), uri.begin(), ::toupper);
|
||||
// convert uri string to route enum
|
||||
ChatWebAPI::eRoute route = magic_enum::enum_cast<ChatWebAPI::eRoute>(uri).value_or(ChatWebAPI::eRoute::INVALID);
|
||||
|
||||
// convert body from cstring to std string
|
||||
std::string body(http_msg->body.buf, http_msg->body.len);
|
||||
|
||||
switch (method) {
|
||||
case eHTTPMethod::GET:
|
||||
HandleGET(reply, route, body);
|
||||
break;
|
||||
case eHTTPMethod::POST:
|
||||
HandlePOST(reply, route, body);
|
||||
break;
|
||||
case eHTTPMethod::PUT:
|
||||
case eHTTPMethod::DELETE:
|
||||
case eHTTPMethod::HEAD:
|
||||
case eHTTPMethod::CONNECT:
|
||||
case eHTTPMethod::OPTIONS:
|
||||
case eHTTPMethod::TRACE:
|
||||
case eHTTPMethod::PATCH:
|
||||
case eHTTPMethod::INVALID:
|
||||
default:
|
||||
reply.status = eHTTPStatusCode::METHOD_NOT_ALLOWED;
|
||||
reply.message = "{\"error\":\"Invalid Method\"}";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mg_http_reply(connection, static_cast<int>(reply.status), json_content_type, reply.message.c_str());
|
||||
}
|
||||
|
||||
|
||||
void HandleRequests(mg_connection* connection, int request, void* request_data) {
|
||||
switch (request) {
|
||||
case MG_EV_HTTP_MSG:
|
||||
HandleHTTPMessage(connection, static_cast<mg_http_message*>(request_data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChatWebAPI::ChatWebAPI() {
|
||||
mg_log_set(MG_LL_NONE);
|
||||
|
Reference in New Issue
Block a user