F4MP/codigos originales/tiltedcode/Code/server/Services/ServerListService.cpp

112 lines
4 KiB
C++
Raw Normal View History

#include <Events/PlayerJoinEvent.h>
#include <Events/PlayerLeaveEvent.h>
#include <Events/UpdateEvent.h>
#include <GameServer.h>
#include <Services/ServerListService.h>
#include <console/Setting.h>
#include <future>
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <httplib.h>
extern Console::Setting<uint32_t> uMaxPlayerCount;
static constexpr char kMasterServerEndpoint[] =
//"http://127.0.0.1:8000";
"https://skyrim-reborn-list.skyrim-together.com";
static Console::Setting bAnnounceServer{"LiveServices:bAnnounceServer", "Whether to list the server on the public server list", false};
ServerListService::ServerListService(World& aWorld, entt::dispatcher& aDispatcher) noexcept
: m_world(aWorld)
, m_updateConnection(aDispatcher.sink<UpdateEvent>().connect<&ServerListService::OnUpdate>(this))
, m_nextAnnounce(std::chrono::seconds(0))
{
if (!bAnnounceServer)
spdlog::warn("bAnnounceServer is set to false. The server will not show up as a public server. "
"If you are just playing with friends, this is probably what you want.");
}
void ServerListService::OnUpdate(const UpdateEvent& acEvent) noexcept
{
if (m_nextAnnounce < std::chrono::steady_clock::now())
{
Announce();
m_nextAnnounce = (std::chrono::steady_clock::now() + std::chrono::minutes(1));
}
}
void ServerListService::OnPlayerJoin(const PlayerJoinEvent& acEvent) noexcept
{
Announce();
m_nextAnnounce = (std::chrono::steady_clock::now() + std::chrono::minutes(1));
}
void ServerListService::OnPlayerLeave(const PlayerLeaveEvent& acEvent) noexcept
{
Announce();
m_nextAnnounce = (std::chrono::steady_clock::now() + std::chrono::minutes(1));
}
void ServerListService::Announce() noexcept
{
std::thread([&]() {
auto* pServer = GameServer::Get();
auto pc = static_cast<uint16_t>(m_world.GetPlayerManager().Count());
if (bAnnounceServer)
m_flags |= kIsPublic;
if (pServer->IsPasswordProtected())
m_flags |= kHasPassword;
const auto& cInfo = pServer->GetInfo();
PostAnnouncement(cInfo.name, cInfo.desc, cInfo.icon_url, pServer->GetPort(), cInfo.tick_rate, pc,
uMaxPlayerCount.value_as<uint16_t>(), cInfo.tagList, bAnnounceServer,
pServer->IsPasswordProtected(), m_flags);
}).detach();
}
void ServerListService::PostAnnouncement(String acName, String acDesc, String acIconUrl, uint16_t aPort, uint16_t aTick,
uint16_t aPlayerCount, uint16_t aPlayerMaxCount, String acTagList,
bool aPublic, bool aPassword, int32 aFlags) noexcept
{
const std::string kVersion{BUILD_COMMIT};
const httplib::Params params{
{"name", std::string(acName.c_str(), acName.size())},
{"desc", std::string(acDesc.c_str(), acDesc.size())},
{"icon_url", std::string(acIconUrl.c_str(), acIconUrl.size())},
{"version", std::string(kVersion.c_str(), kVersion.size())},
{"port", std::to_string(aPort)},
{"tick", std::to_string(aTick)},
{"player_count", std::to_string(aPlayerCount)},
{"max_player_count", std::to_string(aPlayerMaxCount)},
{"tags", std::string(acTagList.c_str(), acTagList.size())},
{"public", aPublic ? "true" : "false"},
{"pass", aPassword ? "true" : "false"},
{"flags", std::to_string(aFlags)},
};
httplib::Client client(kMasterServerEndpoint);
client.enable_server_certificate_verification(false);
client.set_read_timeout(std::chrono::milliseconds(30000));
const auto response = client.Post("/announce", params);
// If we send a 403 it means we banned this server
if (response)
{
if (response->status == 403)
GameServer::Get()->Kill();
else if (response->status != 200)
spdlog::error("Server list error! {}", response->body);
}
else
{
spdlog::error("Server could not reach the server list! {}", to_string(response.error()));
}
}