mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-07-03 00:16:50 +00:00
add auto login
This commit is contained in:
parent
6c67d07ce3
commit
c74967e513
@ -1,6 +1,7 @@
|
||||
#include "ClientNetwork.h"
|
||||
#include "ClientPacket.h"
|
||||
#include "ClientTransport.h"
|
||||
#include "Http.h"
|
||||
#include "Identity.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
@ -258,11 +259,8 @@ void ClientNetwork::handle_login(bmp::ClientPacket& packet) {
|
||||
}),
|
||||
};
|
||||
client_tcp_write(login_result);
|
||||
bmp::ClientPacket change_to_quickjoin {
|
||||
.purpose = bmp::ClientPurpose::StateChangeQuickJoin,
|
||||
};
|
||||
client_tcp_write(change_to_quickjoin);
|
||||
m_client_state = bmp::ClientState::QuickJoin;
|
||||
|
||||
start_quick_join();
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Failed to read json for purpose 0x{:x}: {}", uint16_t(packet.purpose), e.what());
|
||||
disconnect(fmt::format("Invalid json in purpose 0x{:x}, see launcher logs for more info", uint16_t(packet.purpose)));
|
||||
@ -275,27 +273,98 @@ void ClientNetwork::handle_login(bmp::ClientPacket& packet) {
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_quick_join(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_browsing(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
case bmp::ClientPurpose::ServerListRequest: {
|
||||
auto list = load_server_list();
|
||||
if (list.has_value()) {
|
||||
bmp::ClientPacket response {
|
||||
.purpose = bmp::ClientPurpose::ServerListResponse,
|
||||
.raw_data = json_to_vec(list.value()),
|
||||
};
|
||||
client_tcp_write(response);
|
||||
} else {
|
||||
spdlog::error("Failed to load server list: {}", list.error());
|
||||
bmp::ClientPacket err {
|
||||
.purpose = bmp::ClientPurpose::Error,
|
||||
.raw_data = json_to_vec({ "message", list.error() }),
|
||||
};
|
||||
client_tcp_write(err);
|
||||
}
|
||||
} break;
|
||||
case bmp::ClientPurpose::Logout: {
|
||||
spdlog::error("Logout is not yet implemented");
|
||||
} break;
|
||||
case bmp::ClientPurpose::Connect: {
|
||||
try {
|
||||
auto details = json::parse(packet.get_readable_data());
|
||||
std::string host = details.at("host");
|
||||
uint16_t port = details.at("port");
|
||||
spdlog::info("Game requesting to connect to server [{}]:{}", host, port);
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Failed to read json for purpose 0x{:x}: {}", uint16_t(packet.purpose), e.what());
|
||||
disconnect(fmt::format("Invalid json in purpose 0x{:x}, see launcher logs for more info", uint16_t(packet.purpose)));
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_server_identification(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_server_authentication(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_server_mod_download(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_server_session_setup(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_server_playing(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientNetwork::handle_server_leaving(bmp::ClientPacket& packet) {
|
||||
switch (packet.purpose) {
|
||||
default:
|
||||
disconnect(fmt::format("Invalid packet purpose in state 0x{:x}: 0x{:x}", uint16_t(m_client_state), uint16_t(packet.purpose)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bmp::ClientPacket ClientNetwork::client_tcp_read() {
|
||||
@ -329,3 +398,35 @@ std::vector<uint8_t> ClientNetwork::json_to_vec(const nlohmann::json& value) {
|
||||
nlohmann::json ClientNetwork::vec_to_json(const std::vector<uint8_t>& vec) {
|
||||
return json::parse(std::string(vec.begin(), vec.end()));
|
||||
}
|
||||
void ClientNetwork::start_quick_join() {
|
||||
bmp::ClientPacket change_to_quickjoin {
|
||||
.purpose = bmp::ClientPurpose::StateChangeQuickJoin,
|
||||
};
|
||||
client_tcp_write(change_to_quickjoin);
|
||||
m_client_state = bmp::ClientState::QuickJoin;
|
||||
|
||||
// TODO: Implement DoJoin, etc
|
||||
|
||||
start_browsing();
|
||||
}
|
||||
|
||||
void ClientNetwork::start_browsing() {
|
||||
bmp::ClientPacket change_to_browsing {
|
||||
.purpose = bmp::ClientPurpose::StateChangeBrowsing,
|
||||
};
|
||||
client_tcp_write(change_to_browsing);
|
||||
m_client_state = bmp::ClientState::Browsing;
|
||||
}
|
||||
|
||||
Result<nlohmann::json, std::string> ClientNetwork::load_server_list() noexcept {
|
||||
try {
|
||||
auto list = HTTP::Get("https://backend.beammp.com/servers-list");
|
||||
if (list == "-1") {
|
||||
return outcome::failure("Failed to fetch server list, see launcher log for more information.");
|
||||
}
|
||||
json result = json::parse(list);
|
||||
return outcome::success(result);
|
||||
} catch (const std::exception& e) {
|
||||
return outcome::failure(fmt::format("Failed to fetch server list from backend: {}", e.what()));
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,10 @@ private:
|
||||
|
||||
void disconnect(const std::string& reason);
|
||||
void start_login();
|
||||
void start_quick_join();
|
||||
void start_browsing();
|
||||
|
||||
Result<nlohmann::json, std::string> load_server_list() noexcept;
|
||||
|
||||
static std::vector<uint8_t> json_to_vec(const nlohmann::json& json);
|
||||
static nlohmann::json vec_to_json(const std::vector<uint8_t>& vec);
|
||||
|
@ -2,11 +2,13 @@
|
||||
#include "Compression.h"
|
||||
#include "Hashing.h"
|
||||
#include "Http.h"
|
||||
#include "Identity.h"
|
||||
#include "Platform.h"
|
||||
#include "Version.h"
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/iostreams/device/mapped_file.hpp>
|
||||
#include <boost/process.hpp>
|
||||
#include <charconv>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fmt/format.h>
|
||||
@ -15,7 +17,6 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <vector>
|
||||
#include <charconv>
|
||||
|
||||
using namespace boost::asio;
|
||||
|
||||
@ -31,6 +32,8 @@ Launcher::Launcher()
|
||||
if (!m_config->is_valid) {
|
||||
spdlog::error("Launcher config invalid!");
|
||||
}
|
||||
// try logging in immediately, for later update requests and such stuff
|
||||
try_auto_login();
|
||||
}
|
||||
|
||||
/// Sets shared headers for all backend proxy messages
|
||||
@ -52,7 +55,7 @@ void Launcher::proxy_main() {
|
||||
httplib::Client cli("https://backend.beammp.com");
|
||||
proxy_set_headers(res);
|
||||
if (req.has_header("X-BMP-Authentication")) {
|
||||
headers.emplace("X-BMP-Authentication", m_identity->PrivateKey);
|
||||
headers.emplace("X-BMP-Authentication", identity->PrivateKey);
|
||||
}
|
||||
if (req.has_header("X-API-Version")) {
|
||||
headers.emplace("X-API-Version", req.get_header_value("X-API-Version"));
|
||||
@ -68,7 +71,7 @@ void Launcher::proxy_main() {
|
||||
httplib::Client cli("https://backend.beammp.com");
|
||||
proxy_set_headers(res);
|
||||
if (req.has_header("X-BMP-Authentication")) {
|
||||
headers.emplace("X-BMP-Authentication", m_identity->PrivateKey);
|
||||
headers.emplace("X-BMP-Authentication", identity->PrivateKey);
|
||||
}
|
||||
if (req.has_header("X-API-Version")) {
|
||||
headers.emplace("X-API-Version", req.get_header_value("X-API-Version"));
|
||||
@ -95,13 +98,12 @@ void Launcher::parse_config() {
|
||||
}
|
||||
|
||||
void Launcher::check_for_updates(int argc, char** argv) {
|
||||
std::string LatestHash = HTTP::Get(fmt::format("https://backend.beammp.com/sha/launcher?branch={}&pk={}", m_config->branch, m_identity->PublicKey));
|
||||
std::string LatestVersion = HTTP::Get(fmt::format("https://backend.beammp.com/version/launcher?branch={}&pk={}", m_config->branch, m_identity->PublicKey));
|
||||
|
||||
std::string LatestHash = HTTP::Get(fmt::format("https://backend.beammp.com/sha/launcher?branch={}&pk={}", m_config->branch, identity->PublicKey));
|
||||
std::string LatestVersion = HTTP::Get(fmt::format("https://backend.beammp.com/version/launcher?branch={}&pk={}", m_config->branch,identity->PublicKey));
|
||||
std::string DownloadURL = fmt::format("https://backend.beammp.com/builds/launcher?download=true"
|
||||
"&pk={}"
|
||||
"&branch={}",
|
||||
m_identity->PublicKey, m_config->branch);
|
||||
identity->PublicKey, m_config->branch);
|
||||
|
||||
spdlog::debug("Latest hash: {}", LatestHash);
|
||||
spdlog::debug("Latest version: {}", LatestVersion);
|
||||
@ -170,7 +172,7 @@ void Launcher::pre_game() {
|
||||
|
||||
check_mp((std::filesystem::path(m_config->game_dir) / "mods/multiplayer").generic_string());
|
||||
|
||||
std::string LatestHash = HTTP::Get(fmt::format("https://backend.beammp.com/sha/mod?branch={}&pk={}", m_config->branch, m_identity->PublicKey));
|
||||
std::string LatestHash = HTTP::Get(fmt::format("https://backend.beammp.com/sha/mod?branch={}&pk={}", m_config->branch, identity->PublicKey));
|
||||
transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower);
|
||||
LatestHash.erase(std::remove_if(LatestHash.begin(), LatestHash.end(),
|
||||
[](auto const& c) -> bool { return !std::isalnum(c); }),
|
||||
@ -277,5 +279,12 @@ void Launcher::game_main() {
|
||||
void Launcher::start_game() {
|
||||
m_game_thread = boost::scoped_thread<>(&Launcher::game_main, this);
|
||||
}
|
||||
|
||||
void Launcher::try_auto_login() {
|
||||
if (identity->PublicKey.empty() && ident::is_login_cached()) {
|
||||
auto login = ident::login_cached();
|
||||
if (login.has_value()) {
|
||||
*identity = login.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@ public:
|
||||
|
||||
std::string get_public_key();
|
||||
|
||||
Sync<ident::Identity> identity {};
|
||||
|
||||
private:
|
||||
/// Thread main function for the http(s) proxy thread.
|
||||
void proxy_main();
|
||||
@ -42,6 +44,8 @@ private:
|
||||
|
||||
void enable_mp();
|
||||
|
||||
void try_auto_login();
|
||||
|
||||
Sync<bool> m_mod_loaded { false };
|
||||
|
||||
Sync<Config> m_config;
|
||||
|
Loading…
x
Reference in New Issue
Block a user