mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-07-01 23:46:59 +00:00
implement states until session setup
mod download to be implemented fully
This commit is contained in:
parent
8eb8a80d54
commit
03dc3e3505
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -0,0 +1,3 @@
|
||||
[submodule "deps/BeamMP-Protocol"]
|
||||
path = deps/BeamMP-Protocol
|
||||
url = https://github.com/BeamMP/BeamMP-Protocol
|
@ -32,6 +32,7 @@ set(PRJ_HEADERS
|
||||
src/Hashing.h
|
||||
src/Compression.h
|
||||
src/Config.h
|
||||
src/ServerNetwork.h
|
||||
)
|
||||
# add all source files (.cpp) to this, except the one with main()
|
||||
set(PRJ_SOURCES
|
||||
@ -45,6 +46,7 @@ set(PRJ_SOURCES
|
||||
src/Version.cpp
|
||||
src/Hashing.cpp
|
||||
src/Config.cpp
|
||||
src/ServerNetwork.cpp
|
||||
)
|
||||
# set the source file containing main()
|
||||
set(PRJ_MAIN src/main.cpp)
|
||||
|
@ -71,9 +71,7 @@ function(set_project_warnings project_name)
|
||||
-Werror=write-strings
|
||||
-Werror=strict-aliasing -fstrict-aliasing
|
||||
-Werror=missing-declarations
|
||||
-Werror=missing-field-initializers
|
||||
-Werror=ctor-dtor-privacy
|
||||
-Werror=switch-default
|
||||
-Werror=unused-result
|
||||
-Werror=implicit-fallthrough
|
||||
-Wmissing-include-dirs
|
||||
|
1
deps/BeamMP-Protocol
vendored
Submodule
1
deps/BeamMP-Protocol
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ff4a2f5472b997da8947a8b2769a942ccc2d2b20
|
@ -886,3 +886,7 @@ void Launcher::udp_send(const std::string& data) {
|
||||
to_send.insert(to_send.end(), vec.begin(), vec.end());
|
||||
m_udp_socket.send_to(buffer(to_send.data(), to_send.size()), m_udp_endpoint);
|
||||
}
|
||||
std::string Launcher::get_public_key() {
|
||||
return m_identity->PublicKey;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ public:
|
||||
|
||||
void start_network();
|
||||
|
||||
std::string get_public_key();
|
||||
|
||||
private:
|
||||
/// Thread main function for the http(s) proxy thread.
|
||||
void proxy_main();
|
||||
|
@ -1,9 +1,12 @@
|
||||
#include "ServerNetwork.h"
|
||||
#include "ClientInfo.h"
|
||||
#include "Identity.h"
|
||||
#include "ImplementationInfo.h"
|
||||
#include "Launcher.h"
|
||||
#include "ProtocolVersion.h"
|
||||
#include "ServerInfo.h"
|
||||
#include "Util.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
ServerNetwork::ServerNetwork(Launcher& launcher, const ip::tcp::endpoint& ep)
|
||||
@ -30,6 +33,7 @@ void ServerNetwork::run() {
|
||||
.purpose = bmp::Purpose::ProtocolVersion,
|
||||
.raw_data = std::vector<uint8_t>(6),
|
||||
};
|
||||
spdlog::trace("Protocol version: v{}.{}.{}", 1, 0, 0);
|
||||
struct bmp::ProtocolVersion version {
|
||||
.version = {
|
||||
.major = 1,
|
||||
@ -47,6 +51,14 @@ void ServerNetwork::run() {
|
||||
}
|
||||
|
||||
void ServerNetwork::handle_packet(const bmp::Packet& packet) {
|
||||
// handle ping immediately
|
||||
if (m_state > bmp::State::Identification && packet.purpose == bmp::Purpose::Ping) {
|
||||
bmp::Packet pong {
|
||||
.purpose = bmp::Purpose::Ping,
|
||||
};
|
||||
tcp_write(pong);
|
||||
return;
|
||||
}
|
||||
switch (m_state) {
|
||||
case bmp::State::None:
|
||||
m_state = bmp::State::Identification;
|
||||
@ -55,8 +67,10 @@ void ServerNetwork::handle_packet(const bmp::Packet& packet) {
|
||||
handle_identification(packet);
|
||||
break;
|
||||
case bmp::State::Authentication:
|
||||
handle_authentication(packet);
|
||||
break;
|
||||
case bmp::State::ModDownload:
|
||||
handle_mod_download(packet);
|
||||
break;
|
||||
case bmp::State::SessionSetup:
|
||||
break;
|
||||
@ -67,6 +81,79 @@ void ServerNetwork::handle_packet(const bmp::Packet& packet) {
|
||||
}
|
||||
}
|
||||
|
||||
void ServerNetwork::handle_mod_download(const bmp::Packet& packet) {
|
||||
switch (packet.purpose) {
|
||||
case bmp::Purpose::ModsInfo: {
|
||||
auto data = packet.get_readable_data();
|
||||
auto mods_info = nlohmann::json::parse(data.begin(), data.end());
|
||||
spdlog::info("Got info about {} mod(s)", mods_info.size());
|
||||
for (const auto& mod : mods_info) {
|
||||
spdlog::warn("Mod download not implemented, but data is: {}", mod.dump(4));
|
||||
}
|
||||
// TODO: implement mod download
|
||||
// for now we just pretend we're all good!
|
||||
bmp::Packet ok {
|
||||
.purpose = bmp::Purpose::ModsSyncDone,
|
||||
};
|
||||
spdlog::info("Done syncing mods");
|
||||
tcp_write(ok);
|
||||
break;
|
||||
}
|
||||
case bmp::Purpose::StateChangeSessionSetup: {
|
||||
spdlog::info("Starting session setup");
|
||||
m_state = bmp::State::SessionSetup;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
spdlog::error("Got 0x{:x} in state {}. This is not allowed. Disconnecting", uint16_t(packet.purpose), int(m_state));
|
||||
// todo: disconnect gracefully
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerNetwork::handle_authentication(const bmp::Packet& packet) {
|
||||
switch (packet.purpose) {
|
||||
case bmp::Purpose::AuthOk: {
|
||||
spdlog::info("Authentication succeeded");
|
||||
uint32_t player_id;
|
||||
bmp::deserialize(player_id, packet.get_readable_data());
|
||||
spdlog::debug("Player id: {}", player_id);
|
||||
break;
|
||||
}
|
||||
case bmp::Purpose::AuthFailed: {
|
||||
auto data = packet.get_readable_data();
|
||||
spdlog::error("Authentication failed: {}", std::string(data.begin(), data.end()));
|
||||
break;
|
||||
}
|
||||
case bmp::Purpose::PlayerRejected: {
|
||||
auto data = packet.get_readable_data();
|
||||
spdlog::error("Server rejected me: {}", std::string(data.begin(), data.end()));
|
||||
break;
|
||||
}
|
||||
case bmp::Purpose::StartUDP: {
|
||||
bmp::deserialize(m_udp_magic, packet.get_readable_data());
|
||||
spdlog::debug("UDP start, got magic 0x{:x}", m_udp_magic);
|
||||
m_udp_ep = ip::udp::endpoint(m_tcp_ep.address(), m_tcp_ep.port());
|
||||
m_udp_socket.open(m_tcp_ep.address().is_v4() ? ip::udp::v4() : ip::udp::v6());
|
||||
auto copy = bmp::Packet {
|
||||
.purpose = bmp::Purpose::StartUDP,
|
||||
.raw_data = packet.get_readable_data(),
|
||||
};
|
||||
udp_write(copy);
|
||||
break;
|
||||
}
|
||||
case bmp::Purpose::StateChangeModDownload: {
|
||||
spdlog::info("Starting mod sync");
|
||||
m_state = bmp::State::ModDownload;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
spdlog::error("Got 0x{:x} in state {}. This is not allowed. Disconnecting", uint16_t(packet.purpose), int(m_state));
|
||||
// todo: disconnect gracefully
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerNetwork::handle_identification(const bmp::Packet& packet) {
|
||||
switch (packet.purpose) {
|
||||
case bmp::Purpose::ProtocolVersionOk: {
|
||||
@ -106,6 +193,13 @@ void ServerNetwork::handle_identification(const bmp::Packet& packet) {
|
||||
case bmp::Purpose::StateChangeAuthentication: {
|
||||
spdlog::debug("Starting authentication");
|
||||
m_state = bmp::State::Authentication;
|
||||
// TODO: make the launcher provide login properly!
|
||||
auto pubkey = m_launcher.get_public_key();
|
||||
bmp::Packet pubkey_packet {
|
||||
.purpose = bmp::Purpose::PlayerPublicKey,
|
||||
.raw_data = std::vector<uint8_t>(pubkey.begin(), pubkey.end())
|
||||
};
|
||||
tcp_write(pubkey_packet);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -31,6 +31,8 @@ private:
|
||||
|
||||
void handle_packet(const bmp::Packet& packet);
|
||||
void handle_identification(const bmp::Packet& packet);
|
||||
void handle_authentication(const bmp::Packet& packet);
|
||||
void handle_mod_download(const bmp::Packet& packet);
|
||||
|
||||
io_context m_io {};
|
||||
ip::tcp::socket m_tcp_socket { m_io };
|
||||
@ -38,6 +40,8 @@ private:
|
||||
|
||||
bmp::State m_state {};
|
||||
|
||||
uint64_t m_udp_magic {};
|
||||
|
||||
Launcher& m_launcher;
|
||||
|
||||
ip::tcp::endpoint m_tcp_ep;
|
||||
|
36
src/main.cpp
36
src/main.cpp
@ -1,5 +1,8 @@
|
||||
#include "Launcher.h"
|
||||
#include "Platform.h"
|
||||
#include "ServerNetwork.h"
|
||||
#include <boost/system/detail/errc.hpp>
|
||||
#include <boost/system/detail/error_category.hpp>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
@ -16,8 +19,10 @@ int main(int argc, char** argv) {
|
||||
bool enable_dev = false;
|
||||
int custom_port = 0;
|
||||
std::string_view invalid_arg;
|
||||
std::string all_args = std::string { argv[0] } + " ";
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::string_view arg(argv[i]);
|
||||
all_args += "'" + std::string(arg) + "' ";
|
||||
std::string_view next(i + 1 < argc ? argv[i + 1] : "");
|
||||
// --debug flag enables debug printing in console
|
||||
if (arg == "--debug") {
|
||||
@ -37,18 +42,30 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
setup_logger(enable_debug || enable_dev);
|
||||
|
||||
spdlog::debug("Debug enabled");
|
||||
spdlog::trace("BeamMP Launcher invoked as: {}", all_args);
|
||||
|
||||
if (enable_debug) {
|
||||
spdlog::debug("Debug mode enabled");
|
||||
}
|
||||
if (enable_dev) {
|
||||
spdlog::debug("Development mode enabled");
|
||||
}
|
||||
if (custom_port != 0) {
|
||||
spdlog::debug("Custom port set: {}", custom_port);
|
||||
}
|
||||
|
||||
if (!invalid_arg.empty()) {
|
||||
spdlog::warn("Invalid argument passed via commandline switches: '{}'. This argument was ignored.", invalid_arg);
|
||||
spdlog::warn("One or more invalid argument(s) passed via commandline switches, last one: '{}'. This argument was ignored.", invalid_arg);
|
||||
}
|
||||
|
||||
plat::clear_screen();
|
||||
plat::set_console_title(fmt::format("BeamMP Launcher v{}.{}.{}", PRJ_VERSION_MAJOR, PRJ_VERSION_MINOR, PRJ_VERSION_PATCH));
|
||||
spdlog::trace("BeamMP Launcher v{}.{}.{}", PRJ_VERSION_MAJOR, PRJ_VERSION_MINOR, PRJ_VERSION_PATCH);
|
||||
|
||||
spdlog::info("BeamMP Launcher v{}.{}.{} is a PRE-RELEASE build. Please report any errors immediately at https://github.com/BeamMP/BeamMP-Launcher.",
|
||||
PRJ_VERSION_MAJOR, PRJ_VERSION_MINOR, PRJ_VERSION_PATCH);
|
||||
|
||||
/*
|
||||
Launcher launcher {};
|
||||
|
||||
std::filesystem::path arg0(argv[0]);
|
||||
@ -73,7 +90,19 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
launcher.start_network();
|
||||
*/
|
||||
Launcher launcher {};
|
||||
|
||||
std::filesystem::path arg0(argv[0]);
|
||||
launcher.set_exe_name(arg0.filename().generic_string());
|
||||
launcher.set_exe_path(arg0.parent_path());
|
||||
|
||||
try {
|
||||
ServerNetwork sn(launcher, ip::tcp::endpoint(ip::address::from_string("127.0.0.1"), 30814));
|
||||
sn.run();
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Connection to server closed: {}", e.what());
|
||||
}
|
||||
spdlog::info("Shutting down.");
|
||||
}
|
||||
|
||||
@ -88,11 +117,12 @@ void setup_logger(bool debug) {
|
||||
|
||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("Launcher.log", true);
|
||||
file_sink->set_level(spdlog::level::trace);
|
||||
file_sink->set_pattern("[%H:%M:%S.%e] [%t] [%L] %v");
|
||||
|
||||
default_logger = std::make_shared<spdlog::logger>(spdlog::logger("default", { console_sink, file_sink }));
|
||||
|
||||
default_logger->set_level(spdlog::level::trace);
|
||||
default_logger->flush_on(spdlog::level::info);
|
||||
default_logger->flush_on(spdlog::level::trace);
|
||||
|
||||
spdlog::set_default_logger(default_logger);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user