Multiplayer working
This commit is contained in:
parent
106d5ced0b
commit
2af77fa468
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -3,7 +3,7 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"--single",
|
"--single",
|
||||||
"--port",
|
"--port",
|
||||||
"8080"
|
"8080-"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14,4 +14,5 @@ namespace deerith
|
|||||||
float get_window_aspect_ratio();
|
float get_window_aspect_ratio();
|
||||||
|
|
||||||
int get_current_frame_id();
|
int get_current_frame_id();
|
||||||
|
bool is_windows_focused();
|
||||||
}
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <deerith/engine.h>
|
||||||
|
|
||||||
|
namespace deerith
|
||||||
|
{
|
||||||
|
struct chunk_render_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#include "deerith/graphics/shader.h"
|
#include "deerith/graphics/shader.h"
|
||||||
|
#include <deerith/engine.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
@ -6,6 +7,24 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
std::filesystem::path get_executable_directory()
|
||||||
|
{
|
||||||
|
std::array<char, 4096> buffer{};
|
||||||
|
|
||||||
|
const auto length = readlink(
|
||||||
|
"/proc/self/exe",
|
||||||
|
buffer.data(),
|
||||||
|
buffer.size() - 1);
|
||||||
|
|
||||||
|
if (length == -1)
|
||||||
|
throw std::runtime_error("Failed to get executable path");
|
||||||
|
|
||||||
|
return std::filesystem::path(
|
||||||
|
std::string(buffer.data(), length))
|
||||||
|
.parent_path();
|
||||||
|
}
|
||||||
|
|
||||||
deerith::Shader::Shader(const char *vertexPath, const char *fragmentPath)
|
deerith::Shader::Shader(const char *vertexPath, const char *fragmentPath)
|
||||||
{
|
{
|
||||||
@ -23,10 +42,11 @@ deerith::Shader::Shader(const char *vertexPath, const char *fragmentPath)
|
|||||||
std::ifstream::failbit |
|
std::ifstream::failbit |
|
||||||
std::ifstream::badbit);
|
std::ifstream::badbit);
|
||||||
|
|
||||||
|
std::filesystem::path cwd = get_executable_directory();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
vertexFile.open(vertexPath);
|
vertexFile.open(cwd / vertexPath);
|
||||||
fragmentFile.open(fragmentPath);
|
fragmentFile.open(cwd / fragmentPath);
|
||||||
|
|
||||||
std::stringstream vertexStream;
|
std::stringstream vertexStream;
|
||||||
std::stringstream fragmentStream;
|
std::stringstream fragmentStream;
|
||||||
|
|||||||
@ -77,6 +77,11 @@ int deerith::init_window()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool deerith::is_windows_focused()
|
||||||
|
{
|
||||||
|
return window && glfwGetWindowAttrib(window, GLFW_FOCUSED);
|
||||||
|
}
|
||||||
|
|
||||||
bool deerith::begin_window_display()
|
bool deerith::begin_window_display()
|
||||||
{
|
{
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include <deerith/engine.h>
|
#include <deerith/engine.h>
|
||||||
#include <deerith/graphics/input.h>
|
#include <deerith/graphics/input.h>
|
||||||
|
#include <deerith/graphics/window.h>
|
||||||
#include <deerith/network/router.h>
|
#include <deerith/network/router.h>
|
||||||
#include <deerith/network/packets.h>
|
#include <deerith/network/packets.h>
|
||||||
#include <deerith/world/entity.h>
|
#include <deerith/world/entity.h>
|
||||||
@ -15,7 +16,13 @@ void deerith::process_player_input()
|
|||||||
{
|
{
|
||||||
if (self_entity == entt::null)
|
if (self_entity == entt::null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glm::vec2 movment = get_joystick_axes(0, 0);
|
glm::vec2 movment = get_joystick_axes(0, 0);
|
||||||
|
if (!is_windows_focused())
|
||||||
|
{
|
||||||
|
movment = glm::vec2(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
entity_sync_client_position_t &entity_sync_position = get_component<entity_sync_client_position_t>(self_entity);
|
entity_sync_client_position_t &entity_sync_position = get_component<entity_sync_client_position_t>(self_entity);
|
||||||
|
|
||||||
entity_sync_position.move_input = movment;
|
entity_sync_position.move_input = movment;
|
||||||
|
|||||||
@ -13,6 +13,7 @@ void deerith::setup_base_protocols()
|
|||||||
router_add_packet_processor<create_player_entity_packet_t>();
|
router_add_packet_processor<create_player_entity_packet_t>();
|
||||||
router_add_packet_processor<create_entity_packet_t>();
|
router_add_packet_processor<create_entity_packet_t>();
|
||||||
router_add_packet_processor<sync_entities_coordinates_packet_t>();
|
router_add_packet_processor<sync_entities_coordinates_packet_t>();
|
||||||
|
router_add_packet_processor<destroy_entity_packet_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -34,7 +35,17 @@ void deerith::process_packet(deerith::create_entity_packet_t &packet, client_t *
|
|||||||
{
|
{
|
||||||
deerith_trace("creating entity with network id {}", packet.network_sync_id);
|
deerith_trace("creating entity with network id {}", packet.network_sync_id);
|
||||||
|
|
||||||
entity_t entity = create_entity();
|
entity_t entity;
|
||||||
|
if (packet.is_self_client)
|
||||||
|
{
|
||||||
|
deerith_trace("creating self entity");
|
||||||
|
entity = self_entity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entity = create_entity();
|
||||||
|
}
|
||||||
|
|
||||||
entity_network_id_t &entity_network_id = add_entity_network_with_id(entity, packet.network_sync_id);
|
entity_network_id_t &entity_network_id = add_entity_network_with_id(entity, packet.network_sync_id);
|
||||||
|
|
||||||
if (packet.add_entity_sync_coordinates)
|
if (packet.add_entity_sync_coordinates)
|
||||||
@ -60,3 +71,11 @@ void deerith::process_packet(deerith::sync_entities_coordinates_packet_t &packet
|
|||||||
packet.positions_to_update[i].recive(sync_coords.position);
|
packet.positions_to_update[i].recive(sync_coords.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void deerith::process_packet(deerith::destroy_entity_packet_t &packet, client_t *client)
|
||||||
|
{
|
||||||
|
deerith_trace("destroying entity : {}", packet.network_sync_id);
|
||||||
|
entity_t specific_entity = get_network_entity_with_id(packet.network_sync_id);
|
||||||
|
get_entity_registry().destroy(specific_entity);
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@ void deerith::render_world()
|
|||||||
{
|
{
|
||||||
define_primitive_viewspace(glm::vec2(-10, -10), glm::vec2(10, 10));
|
define_primitive_viewspace(glm::vec2(-10, -10), glm::vec2(10, 10));
|
||||||
|
|
||||||
auto entities_view = get_entity_registry().view<entity_sync_coordinates_t>();
|
auto entities_view = get_entity_registry().view<entity_sync_coordinates_t>(entt::exclude<entity_sync_client_position_t>);
|
||||||
for (auto [entity, sync_coords] : entities_view.each())
|
for (auto [entity, sync_coords] : entities_view.each())
|
||||||
{
|
{
|
||||||
glm::vec2 chords;
|
glm::vec2 chords;
|
||||||
@ -17,4 +17,12 @@ void deerith::render_world()
|
|||||||
draw_primitive_rectangle(chords - glm::vec2(0.5f, 0.5f), chords + glm::vec2(0.5f, 0.5f));
|
draw_primitive_rectangle(chords - glm::vec2(0.5f, 0.5f), chords + glm::vec2(0.5f, 0.5f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we should expect only one registry
|
||||||
|
auto self_view = get_entity_registry().view<entity_sync_coordinates_t, entity_sync_client_position_t>();
|
||||||
|
for (auto [entity, sync_coords, client_sync_coords] : self_view.each())
|
||||||
|
{
|
||||||
|
define_primitive_color(glm::vec4(1, 0.5f, 0.6f, 1));
|
||||||
|
draw_primitive_rectangle(client_sync_coords.position.read_value() - glm::vec2(0.5f, 0.5f), client_sync_coords.position.read_value() + glm::vec2(0.5f, 0.5f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +84,10 @@ namespace cereal
|
|||||||
public:
|
public:
|
||||||
//! Represents desired endianness
|
//! Represents desired endianness
|
||||||
enum class Endianness : std::uint8_t
|
enum class Endianness : std::uint8_t
|
||||||
{ big, little };
|
{
|
||||||
|
big,
|
||||||
|
little
|
||||||
|
};
|
||||||
|
|
||||||
//! Default options, preserve system endianness
|
//! Default options, preserve system endianness
|
||||||
static Options Default() { return Options(); }
|
static Options Default() { return Options(); }
|
||||||
@ -97,17 +100,20 @@ namespace cereal
|
|||||||
|
|
||||||
//! Specify specific options for the PortableBinaryOutputArchive
|
//! Specify specific options for the PortableBinaryOutputArchive
|
||||||
/*! @param outputEndian The desired endianness of saved (output) data */
|
/*! @param outputEndian The desired endianness of saved (output) data */
|
||||||
explicit Options( Endianness outputEndian = getEndianness() ) :
|
explicit Options(Endianness outputEndian = getEndianness()) : itsOutputEndianness(outputEndian) {}
|
||||||
itsOutputEndianness( outputEndian ) { }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Gets the endianness of the system
|
//! Gets the endianness of the system
|
||||||
inline static Endianness getEndianness()
|
inline static Endianness getEndianness()
|
||||||
{ return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }
|
{
|
||||||
|
return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big;
|
||||||
|
}
|
||||||
|
|
||||||
//! Checks if Options is set for little endian
|
//! Checks if Options is set for little endian
|
||||||
inline std::uint8_t is_little_endian() const
|
inline std::uint8_t is_little_endian() const
|
||||||
{ return itsOutputEndianness == Endianness::little; }
|
{
|
||||||
|
return itsOutputEndianness == Endianness::little;
|
||||||
|
}
|
||||||
|
|
||||||
friend class PortableBinaryOutputArchive;
|
friend class PortableBinaryOutputArchive;
|
||||||
Endianness itsOutputEndianness;
|
Endianness itsOutputEndianness;
|
||||||
@ -117,8 +123,7 @@ namespace cereal
|
|||||||
/*! @param stream The stream to output to. Should be opened with std::ios::binary flag.
|
/*! @param stream The stream to output to. Should be opened with std::ios::binary flag.
|
||||||
@param options The PortableBinary specific options to use. See the Options struct
|
@param options The PortableBinary specific options to use. See the Options struct
|
||||||
for the values of default parameters */
|
for the values of default parameters */
|
||||||
PortableBinaryOutputArchive(std::ostream & stream, Options const & options = Options::Default()) :
|
PortableBinaryOutputArchive(std::ostream &stream, Options const &options = Options::Default()) : OutputArchive<PortableBinaryOutputArchive, AllowEmptyClassElision>(this),
|
||||||
OutputArchive<PortableBinaryOutputArchive, AllowEmptyClassElision>(this),
|
|
||||||
itsStream(stream),
|
itsStream(stream),
|
||||||
itsConvertEndianness(portable_binary_detail::is_little_endian() ^ options.is_little_endian())
|
itsConvertEndianness(portable_binary_detail::is_little_endian() ^ options.is_little_endian())
|
||||||
{
|
{
|
||||||
@ -128,8 +133,8 @@ namespace cereal
|
|||||||
~PortableBinaryOutputArchive() CEREAL_NOEXCEPT = default;
|
~PortableBinaryOutputArchive() CEREAL_NOEXCEPT = default;
|
||||||
|
|
||||||
//! Writes size bytes of data to the output stream
|
//! Writes size bytes of data to the output stream
|
||||||
template <std::streamsize DataSize> inline
|
template <std::streamsize DataSize>
|
||||||
void saveBinary( const void * data, std::streamsize size )
|
inline void saveBinary(const void *data, std::streamsize size)
|
||||||
{
|
{
|
||||||
std::streamsize writtenSize = 0;
|
std::streamsize writtenSize = 0;
|
||||||
|
|
||||||
@ -186,7 +191,10 @@ namespace cereal
|
|||||||
public:
|
public:
|
||||||
//! Represents desired endianness
|
//! Represents desired endianness
|
||||||
enum class Endianness : std::uint8_t
|
enum class Endianness : std::uint8_t
|
||||||
{ big, little };
|
{
|
||||||
|
big,
|
||||||
|
little
|
||||||
|
};
|
||||||
|
|
||||||
//! Default options, preserve system endianness
|
//! Default options, preserve system endianness
|
||||||
static Options Default() { return Options(); }
|
static Options Default() { return Options(); }
|
||||||
@ -199,17 +207,20 @@ namespace cereal
|
|||||||
|
|
||||||
//! Specify specific options for the PortableBinaryInputArchive
|
//! Specify specific options for the PortableBinaryInputArchive
|
||||||
/*! @param inputEndian The desired endianness of loaded (input) data */
|
/*! @param inputEndian The desired endianness of loaded (input) data */
|
||||||
explicit Options( Endianness inputEndian = getEndianness() ) :
|
explicit Options(Endianness inputEndian = getEndianness()) : itsInputEndianness(inputEndian) {}
|
||||||
itsInputEndianness( inputEndian ) { }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Gets the endianness of the system
|
//! Gets the endianness of the system
|
||||||
inline static Endianness getEndianness()
|
inline static Endianness getEndianness()
|
||||||
{ return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }
|
{
|
||||||
|
return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big;
|
||||||
|
}
|
||||||
|
|
||||||
//! Checks if Options is set for little endian
|
//! Checks if Options is set for little endian
|
||||||
inline std::uint8_t is_little_endian() const
|
inline std::uint8_t is_little_endian() const
|
||||||
{ return itsInputEndianness == Endianness::little; }
|
{
|
||||||
|
return itsInputEndianness == Endianness::little;
|
||||||
|
}
|
||||||
|
|
||||||
friend class PortableBinaryInputArchive;
|
friend class PortableBinaryInputArchive;
|
||||||
Endianness itsInputEndianness;
|
Endianness itsInputEndianness;
|
||||||
@ -219,8 +230,7 @@ namespace cereal
|
|||||||
/*! @param stream The stream to read from. Should be opened with std::ios::binary flag.
|
/*! @param stream The stream to read from. Should be opened with std::ios::binary flag.
|
||||||
@param options The PortableBinary specific options to use. See the Options struct
|
@param options The PortableBinary specific options to use. See the Options struct
|
||||||
for the values of default parameters */
|
for the values of default parameters */
|
||||||
PortableBinaryInputArchive(std::istream & stream, Options const & options = Options::Default()) :
|
PortableBinaryInputArchive(std::istream &stream, Options const &options = Options::Default()) : InputArchive<PortableBinaryInputArchive, AllowEmptyClassElision>(this),
|
||||||
InputArchive<PortableBinaryInputArchive, AllowEmptyClassElision>(this),
|
|
||||||
itsStream(stream),
|
itsStream(stream),
|
||||||
itsConvertEndianness(false)
|
itsConvertEndianness(false)
|
||||||
{
|
{
|
||||||
@ -235,8 +245,8 @@ namespace cereal
|
|||||||
/*! @param data The data to save
|
/*! @param data The data to save
|
||||||
@param size The number of bytes in the data
|
@param size The number of bytes in the data
|
||||||
@tparam DataSize T The size of the actual type of the data elements being loaded */
|
@tparam DataSize T The size of the actual type of the data elements being loaded */
|
||||||
template <std::streamsize DataSize> inline
|
template <std::streamsize DataSize>
|
||||||
void loadBinary( void * const data, std::streamsize size )
|
inline void loadBinary(void *const data, std::streamsize size)
|
||||||
{
|
{
|
||||||
// load data
|
// load data
|
||||||
auto const readSize = itsStream.rdbuf()->sgetn(reinterpret_cast<char *>(data), size);
|
auto const readSize = itsStream.rdbuf()->sgetn(reinterpret_cast<char *>(data), size);
|
||||||
@ -262,7 +272,8 @@ namespace cereal
|
|||||||
// Common BinaryArchive serialization functions
|
// Common BinaryArchive serialization functions
|
||||||
|
|
||||||
//! Saving for POD types to portable binary
|
//! Saving for POD types to portable binary
|
||||||
template<class T> inline
|
template <class T>
|
||||||
|
inline
|
||||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||||
CEREAL_SAVE_FUNCTION_NAME(PortableBinaryOutputArchive &ar, T const &t)
|
CEREAL_SAVE_FUNCTION_NAME(PortableBinaryOutputArchive &ar, T const &t)
|
||||||
{
|
{
|
||||||
@ -273,7 +284,8 @@ namespace cereal
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Loading for POD types from portable binary
|
//! Loading for POD types from portable binary
|
||||||
template<class T> inline
|
template <class T>
|
||||||
|
inline
|
||||||
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
|
||||||
CEREAL_LOAD_FUNCTION_NAME(PortableBinaryInputArchive &ar, T &t)
|
CEREAL_LOAD_FUNCTION_NAME(PortableBinaryInputArchive &ar, T &t)
|
||||||
{
|
{
|
||||||
@ -284,24 +296,24 @@ namespace cereal
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Serializing NVP types to portable binary
|
//! Serializing NVP types to portable binary
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T>
|
||||||
CEREAL_ARCHIVE_RESTRICT(PortableBinaryInputArchive, PortableBinaryOutputArchive)
|
inline CEREAL_ARCHIVE_RESTRICT(PortableBinaryInputArchive, PortableBinaryOutputArchive)
|
||||||
CEREAL_SERIALIZE_FUNCTION_NAME(Archive &ar, NameValuePair<T> &t)
|
CEREAL_SERIALIZE_FUNCTION_NAME(Archive &ar, NameValuePair<T> &t)
|
||||||
{
|
{
|
||||||
ar(t.value);
|
ar(t.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Serializing SizeTags to portable binary
|
//! Serializing SizeTags to portable binary
|
||||||
template <class Archive, class T> inline
|
template <class Archive, class T>
|
||||||
CEREAL_ARCHIVE_RESTRICT(PortableBinaryInputArchive, PortableBinaryOutputArchive)
|
inline CEREAL_ARCHIVE_RESTRICT(PortableBinaryInputArchive, PortableBinaryOutputArchive)
|
||||||
CEREAL_SERIALIZE_FUNCTION_NAME(Archive &ar, SizeTag<T> &t)
|
CEREAL_SERIALIZE_FUNCTION_NAME(Archive &ar, SizeTag<T> &t)
|
||||||
{
|
{
|
||||||
ar(t.size);
|
ar(t.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Saving binary data to portable binary
|
//! Saving binary data to portable binary
|
||||||
template <class T> inline
|
template <class T>
|
||||||
void CEREAL_SAVE_FUNCTION_NAME(PortableBinaryOutputArchive & ar, BinaryData<T> const & bd)
|
inline void CEREAL_SAVE_FUNCTION_NAME(PortableBinaryOutputArchive &ar, BinaryData<T> const &bd)
|
||||||
{
|
{
|
||||||
typedef typename std::remove_pointer<T>::type TT;
|
typedef typename std::remove_pointer<T>::type TT;
|
||||||
static_assert(!std::is_floating_point<TT>::value ||
|
static_assert(!std::is_floating_point<TT>::value ||
|
||||||
@ -312,8 +324,8 @@ namespace cereal
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Loading binary data from portable binary
|
//! Loading binary data from portable binary
|
||||||
template <class T> inline
|
template <class T>
|
||||||
void CEREAL_LOAD_FUNCTION_NAME(PortableBinaryInputArchive & ar, BinaryData<T> & bd)
|
inline void CEREAL_LOAD_FUNCTION_NAME(PortableBinaryInputArchive &ar, BinaryData<T> &bd)
|
||||||
{
|
{
|
||||||
typedef typename std::remove_pointer<T>::type TT;
|
typedef typename std::remove_pointer<T>::type TT;
|
||||||
static_assert(!std::is_floating_point<TT>::value ||
|
static_assert(!std::is_floating_point<TT>::value ||
|
||||||
|
|||||||
@ -47,14 +47,16 @@ namespace deerith
|
|||||||
static constexpr uint16_t packet_id = 4;
|
static constexpr uint16_t packet_id = 4;
|
||||||
static constexpr bool reliable = true;
|
static constexpr bool reliable = true;
|
||||||
|
|
||||||
id_t network_sync_id;
|
id_t network_sync_id = 0;
|
||||||
bool add_entity_sync_coordinates;
|
bool add_entity_sync_coordinates = false;
|
||||||
|
bool is_self_client = false;
|
||||||
|
|
||||||
template <typename Archive>
|
template <typename Archive>
|
||||||
void serialize(Archive &archive)
|
void serialize(Archive &archive)
|
||||||
{
|
{
|
||||||
archive(network_sync_id);
|
archive(network_sync_id);
|
||||||
archive(add_entity_sync_coordinates);
|
archive(add_entity_sync_coordinates);
|
||||||
|
archive(is_self_client);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,4 +75,18 @@ namespace deerith
|
|||||||
archive(positions_to_update);
|
archive(positions_to_update);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct destroy_entity_packet_t
|
||||||
|
{
|
||||||
|
static constexpr uint16_t packet_id = 6;
|
||||||
|
static constexpr bool reliable = true;
|
||||||
|
|
||||||
|
id_t network_sync_id = 0;
|
||||||
|
|
||||||
|
template <typename Archive>
|
||||||
|
void serialize(Archive &archive)
|
||||||
|
{
|
||||||
|
archive(network_sync_id);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -1,9 +0,0 @@
|
|||||||
#include "network/network_internals.h"
|
|
||||||
#include <deerith/network/router.h>
|
|
||||||
|
|
||||||
#include <deerith/network/packets.h>
|
|
||||||
|
|
||||||
void deerith::load_base_protocols()
|
|
||||||
{
|
|
||||||
router_add_packet_processor<sync_entity_player_position_packet_t>();
|
|
||||||
}
|
|
||||||
@ -21,6 +21,21 @@ namespace deerith
|
|||||||
std::vector<std::unique_ptr<client_t>> clients;
|
std::vector<std::unique_ptr<client_t>> clients;
|
||||||
|
|
||||||
void create_client(ENetPeer *peer);
|
void create_client(ENetPeer *peer);
|
||||||
|
void delete_client(client_t *client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::delete_client(client_t *client)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(
|
||||||
|
clients.begin(),
|
||||||
|
clients.end(),
|
||||||
|
[client](const std::unique_ptr<client_t> &ptr)
|
||||||
|
{ return ptr.get() == client; });
|
||||||
|
|
||||||
|
if (it != clients.end())
|
||||||
|
{
|
||||||
|
clients.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deerith::init_server(int port)
|
bool deerith::init_server(int port)
|
||||||
@ -71,6 +86,8 @@ void deerith::flush_network_events()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
|
client_disconnects((client_t *)event.peer->data);
|
||||||
|
delete_client((client_t *)event.peer->data);
|
||||||
event.peer->data = NULL;
|
event.peer->data = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,10 @@ namespace deerith
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void deerith::load_base_protocols()
|
||||||
|
{
|
||||||
|
router_add_packet_processor<sync_entity_player_position_packet_t>();
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void deerith::process_packet(sync_entity_player_position_packet_t &packet, client_t *client)
|
void deerith::process_packet(sync_entity_player_position_packet_t &packet, client_t *client)
|
||||||
@ -32,37 +36,85 @@ void deerith::client_connects(client_t *client)
|
|||||||
|
|
||||||
// create entity player entity
|
// create entity player entity
|
||||||
entity_t entity = create_entity();
|
entity_t entity = create_entity();
|
||||||
entity_link_to_client_t &link = add_component<entity_link_to_client_t>(entity);
|
|
||||||
entity_sync_client_position_t &position_sync = add_component<entity_sync_client_position_t>(entity);
|
entity_sync_client_position_t &position_sync = add_component<entity_sync_client_position_t>(entity);
|
||||||
|
|
||||||
create_player_entity_packet_t create_player_entity;
|
create_player_entity_packet_t create_player_entity;
|
||||||
router_send_packet(create_player_entity, client);
|
router_send_packet(create_player_entity, client);
|
||||||
|
|
||||||
link.client = client;
|
|
||||||
client->entity_id = entity;
|
|
||||||
|
|
||||||
// create the server representation of the entity
|
// create the server representation of the entity
|
||||||
add_entity_network_id(entity);
|
add_entity_network_id(entity);
|
||||||
add_component<entity_sync_coordinates_t>(entity);
|
add_component<entity_sync_coordinates_t>(entity);
|
||||||
|
|
||||||
send_create_entity_to_all_clients(entity);
|
send_create_entity_to_all_clients(entity);
|
||||||
|
|
||||||
|
// we do this the last to avoid send_create_entity_to_all_clients send_create_actual_entities_to_client create the same entity for the player
|
||||||
|
entity_link_to_client_t &link = add_component<entity_link_to_client_t>(entity);
|
||||||
|
client->entity_id = entity;
|
||||||
|
link.client = client;
|
||||||
|
|
||||||
|
send_create_actual_entities_to_client(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deerith::send_create_entity_to_all_clients(deerith::entity_t ent)
|
void deerith::send_create_entity_to_all_clients(deerith::entity_t ent)
|
||||||
|
{
|
||||||
|
auto view = get_entity_registry().view<entity_link_to_client_t>();
|
||||||
|
for (auto [entity, link_to_client] : view.each())
|
||||||
|
{
|
||||||
|
send_create_entity_to_client(ent, link_to_client.client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::send_create_entity_to_client(entity_t ent, client_t *client)
|
||||||
{
|
{
|
||||||
entity_network_id_t &entity_network_id = get_component<entity_network_id_t>(ent);
|
entity_network_id_t &entity_network_id = get_component<entity_network_id_t>(ent);
|
||||||
|
|
||||||
create_entity_packet_t create_entity;
|
create_entity_packet_t create_entity;
|
||||||
create_entity.network_sync_id = entity_network_id.network_id;
|
create_entity.network_sync_id = entity_network_id.network_id;
|
||||||
|
|
||||||
|
// in case its the self entity we let it know to the client
|
||||||
if (has_component<entity_link_to_client_t>(ent))
|
if (has_component<entity_link_to_client_t>(ent))
|
||||||
|
{
|
||||||
|
entity_link_to_client_t &link = get_component<entity_link_to_client_t>(ent);
|
||||||
|
create_entity.is_self_client = link.client == client;
|
||||||
|
deerith_trace("entity could be self {}", create_entity.is_self_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_component<entity_sync_coordinates_t>(ent))
|
||||||
{
|
{
|
||||||
create_entity.add_entity_sync_coordinates = true;
|
create_entity.add_entity_sync_coordinates = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router_send_packet(create_entity, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::client_disconnects(client_t *client)
|
||||||
|
{
|
||||||
|
entity_t client_entity = client->entity_id;
|
||||||
|
send_delete_entity_to_all_clients(client_entity);
|
||||||
|
|
||||||
|
get_entity_registry().destroy(client_entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::send_delete_entity_to_all_clients(entity_t ent)
|
||||||
|
{
|
||||||
|
destroy_entity_packet_t destroy_entity;
|
||||||
|
entity_network_id_t &network_id = get_component<entity_network_id_t>(ent);
|
||||||
|
|
||||||
|
destroy_entity.network_sync_id = network_id.network_id;
|
||||||
|
|
||||||
auto view = get_entity_registry().view<entity_link_to_client_t>();
|
auto view = get_entity_registry().view<entity_link_to_client_t>();
|
||||||
for (auto [entity, link_to_client] : view.each())
|
for (auto [entity, link_to_client] : view.each())
|
||||||
{
|
{
|
||||||
router_send_packet(create_entity, link_to_client.client);
|
router_send_packet(destroy_entity, link_to_client.client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deerith::send_create_actual_entities_to_client(client_t *client)
|
||||||
|
{
|
||||||
|
auto entities_view = get_entity_registry().view<entity_network_id_t>();
|
||||||
|
|
||||||
|
for (auto [ent, network_id] : entities_view.each())
|
||||||
|
{
|
||||||
|
send_create_entity_to_client(ent, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,8 +6,13 @@ namespace deerith
|
|||||||
{
|
{
|
||||||
void update_players_characters();
|
void update_players_characters();
|
||||||
void client_connects(client_t *client);
|
void client_connects(client_t *client);
|
||||||
|
void client_disconnects(client_t *client);
|
||||||
|
|
||||||
void send_entity_data();
|
void send_entity_data();
|
||||||
|
|
||||||
void send_create_entity_to_all_clients(entity_t ent);
|
void send_create_entity_to_all_clients(entity_t ent);
|
||||||
|
void send_create_entity_to_client(entity_t ent, client_t *client);
|
||||||
|
void send_create_actual_entities_to_client(client_t *client);
|
||||||
|
|
||||||
|
void send_delete_entity_to_all_clients(entity_t ent);
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user