implement vehicle specifics, code needed for the rest of the server

This commit is contained in:
Lion Kortlepel
2024-01-19 17:33:53 +01:00
parent b882174ae7
commit e0fe6693e0
2 changed files with 262 additions and 23 deletions

View File

@@ -1,14 +1,22 @@
#pragma once
#include "Common.h"
#include "Packet.h"
#include "State.h"
#include "Sync.h"
#include "Transport.h"
#include "Packet.h"
#include <boost/asio.hpp>
#include <boost/thread/scoped_thread.hpp>
#include <boost/thread/synchronized_value.hpp>
#include <cstdint>
#include <filesystem>
#include <glm/detail/qualifier.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <memory>
#include <mutex>
#include <nlohmann/json.hpp>
#include <optional>
#include <unordered_map>
#include <vector>
@@ -17,11 +25,10 @@ using VehicleID = uint16_t;
using namespace boost::asio;
struct Client {
using Ptr = std::shared_ptr<Client>;
ClientID id;
bmp::State state { bmp::State::None };
Sync<bmp::State> state { bmp::State::None };
Sync<std::string> name;
Sync<std::string> role;
@@ -64,8 +71,51 @@ private:
struct Vehicle {
using Ptr = std::shared_ptr<Vehicle>;
ClientID owner;
std::vector<uint8_t> data;
Sync<ClientID> owner;
Sync<std::vector<uint8_t>> data;
struct Status {
glm::vec3 rvel {};
glm::vec4 rot {};
glm::vec3 vel {};
glm::vec3 pos {};
float time {};
};
Status get_status() {
std::unique_lock lock(m_mtx);
refresh_cache(lock);
return {
.rvel = m_rvel,
.rot = m_rot,
.vel = m_vel,
.pos = m_pos,
.time = m_time,
};
}
void update_status(const std::vector<uint8_t>& raw_packet) {
std::unique_lock lock(m_mtx);
m_needs_refresh = true;
m_status_data = raw_packet;
}
private:
std::recursive_mutex m_mtx;
/// Holds pos, rvel, vel, etc. raw, updated every time
/// such a packet arrives.
std::vector<uint8_t> m_status_data;
/// Parses the status_data on request sets needs_refresh = false.
void refresh_cache(std::unique_lock<std::recursive_mutex>& lock);
bool m_needs_refresh = true;
glm::vec3 m_rvel {};
glm::vec4 m_rot {};
glm::vec3 m_vel {};
glm::vec3 m_pos {};
float m_time {};
};
class Network {
@@ -73,16 +123,51 @@ public:
Network();
~Network();
friend Client;
void disconnect(ClientID id, const std::string& msg);
void send_to(ClientID id, const bmp::Packet& packet);
/// Returns a map of <id, client> containing only clients which are
/// fully connected, i.e. who have mods downloaded and everything spawned in.
/// If you're unsure which to use, use this one.
std::unordered_map<ClientID, Client::Ptr> playing_clients() const;
/// Returns a map of <id, client> containing only clients who are authenticated.
std::unordered_map<ClientID, Client::Ptr> authenticated_clients() const;
/// Returns all clients, including non-authenticated clients. Use only for debugging,
/// information, stats, status.
std::unordered_map<ClientID, Client::Ptr> all_clients() const;
std::optional<Client::Ptr> get_client(ClientID id, bmp::State min_state) const;
std::unordered_map<VehicleID, Vehicle::Ptr> get_vehicles_owned_by(ClientID id);
std::optional<Vehicle::Ptr> get_vehicle(VehicleID id) {
auto vehicles = m_vehicles.synchronize();
if (vehicles->contains(id)) {
return vehicles->at(id);
} else {
return std::nullopt;
}
}
size_t authenticated_client_count() const;
size_t clients_in_state_count(bmp::State state) const;
size_t guest_count() const;
size_t vehicle_count() const;
private:
void handle_packet(ClientID id, const bmp::Packet& packet);
/// Reads a packet from the given UDP socket, returning the client's endpoint as an out-argument.
bmp::Packet udp_read(ip::udp::endpoint& out_ep);
/// Sends a packet to the specified UDP endpoint via the UDP socket.
void udp_write(bmp::Packet& packet, const ip::udp::endpoint& to_ep);
void disconnect(ClientID id, const std::string& msg);
void handle_packet(ClientID i, const bmp::Packet& packet);
private:
void udp_read_main();
void tcp_listen_main();