이대로 제출해버릴까..
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "utils/snowflake.h"
|
||||
|
||||
extern std::uint8_t CLIENTID;
|
||||
|
||||
@@ -6,5 +7,5 @@ namespace veng {
|
||||
class Engine;
|
||||
}
|
||||
|
||||
void BeginPlay(veng::Engine& engine);
|
||||
void BeginPlay(veng::Engine& engine, utils::Snowflake playerID);
|
||||
void Tick(veng::Engine& engine, std::float_t delta_time);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "asteroid/game.h"
|
||||
#include "vulkan_engine/vulkan/engine.h"
|
||||
#include "utils/ConfigManager.h"
|
||||
|
||||
void BeginPlay(veng::Engine& engine) {
|
||||
void BeginPlay(veng::Engine& engine, utils::Snowflake playerID) {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen = std::mt19937(rd());
|
||||
std::uniform_real_distribution<float> jitterDist =
|
||||
@@ -11,6 +12,8 @@ void BeginPlay(veng::Engine& engine) {
|
||||
engine.SpawnLifedModel("player", "player", -1);
|
||||
{
|
||||
std::lock_guard lock(player->modding);
|
||||
if (playerID.snowflake != 0)
|
||||
player->ID = playerID;
|
||||
player->position = glm::vec3(jitterDist(gen), jitterDist(gen), 0.f);
|
||||
player->scale = glm::vec3(.02f);
|
||||
player->colision = true;
|
||||
@@ -46,7 +49,7 @@ void BeginPlay(veng::Engine& engine) {
|
||||
player_flame->needsUpdate = true;
|
||||
}
|
||||
|
||||
std::shared_ptr<veng::Model> const other_player =
|
||||
/*std::shared_ptr<veng::Model> const other_player =
|
||||
engine.SpawnLifedModel("player", "other_player", -1);
|
||||
{
|
||||
std::lock_guard lock(other_player->modding);
|
||||
@@ -74,7 +77,7 @@ void BeginPlay(veng::Engine& engine) {
|
||||
other->shouldBeDestroyed = true;
|
||||
};
|
||||
other_player->colision = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
std::shared_ptr<veng::Model> const camera_lag =
|
||||
engine.SpawnLifedModel("", "camera_lag", -1);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "socket/tcp_socket.h"
|
||||
#include "socket/udp_socket.h"
|
||||
#include "socket/wsa_manager.h"
|
||||
#include "utils/ConfigManager.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/snowflake.h"
|
||||
#include "utils/utils.h"
|
||||
@@ -17,21 +18,21 @@ std::uint8_t CLIENTID = 0;
|
||||
|
||||
std::int32_t main(std::int32_t argc, gsl::zstring* argv) {
|
||||
Network::WSAManager wsamanager;
|
||||
#if !defined(NDEBUG)
|
||||
utils::setDefaultLogger(spdlog::level::level_enum::debug, "log.log", 1024, 2);
|
||||
#endif
|
||||
|
||||
auto config = utils::ConfigManager::load();
|
||||
utils::setDefaultLogger(config.logLevel, config.logFileName,
|
||||
config.logfileSize, config.logfileCount);
|
||||
|
||||
utils::ThreadPool tp(0);
|
||||
Network::IOCP iocp;
|
||||
iocp.init(&tp, SessionProtocol::TCP);
|
||||
|
||||
Network::Address addr;
|
||||
in6_addr in6addr;
|
||||
|
||||
addr.set(AF_INET6, "::1", 9010);
|
||||
addr.set(config.ipVersion, config.IP, config.Port);
|
||||
|
||||
std::shared_ptr<Network::TCPSocket> TCPSock =
|
||||
std::make_shared<Network::TCPSocket>();
|
||||
TCPSock->init(AF_INET6);
|
||||
std::make_shared<Network::TCPSocket>(config.ipVersion);
|
||||
if (TCPSock->connect(addr) == INVALID_SOCKET) {
|
||||
spdlog::error("connect()");
|
||||
std::exit(EXIT_FAILURE);
|
||||
@@ -61,11 +62,19 @@ std::int32_t main(std::int32_t argc, gsl::zstring* argv) {
|
||||
engine.LoadModelAsset("assets/bullet.fbx", "bullet");
|
||||
engine.LoadModelAsset("assets/background.fbx", "background");
|
||||
|
||||
engine.BeginPlay = BeginPlay;
|
||||
engine.BeginPlay = [ID64 = config.playerid](veng::Engine& engine) {
|
||||
utils::Snowflake ID;
|
||||
ID.snowflake = ID64;
|
||||
BeginPlay(engine, ID);
|
||||
};
|
||||
engine.Tick = Tick;
|
||||
|
||||
engine.init();
|
||||
|
||||
std::shared_ptr<veng::Model> const player = engine.GetSpawnedObject("player");
|
||||
config.playerid = player->ID.snowflake;
|
||||
utils::ConfigManager::save(config);
|
||||
|
||||
tp.enqueueJob(
|
||||
[engine = &engine, TCPSock](utils::ThreadPool* tp, std::uint32_t __) {
|
||||
engine->ResponseToServerAndRefresh(TCPSock);
|
||||
|
||||
@@ -90,6 +90,7 @@ void Tick(veng::Engine& engine, std::float_t delta_time) {
|
||||
bullet->linear_velocity = player->linear_velocity + forward * 10.f;
|
||||
bullet->position = player->position + forward * player->scale.x * 10.f;
|
||||
bullet->owner = player;
|
||||
bullet->OwnerID = player->ID;
|
||||
bullet->scale = player->scale;
|
||||
bullet->colision = true;
|
||||
bullet->OnColision = [](utils::ThreadPool* thread_pool,
|
||||
|
||||
60
Client/src/utils/ConfigManager.cpp
Normal file
60
Client/src/utils/ConfigManager.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "Utils/ConfigManager.h"
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
Config ConfigManager::load() {
|
||||
Config config;
|
||||
|
||||
std::ifstream configfile("config.json", std::ifstream::binary);
|
||||
if (!configfile.is_open()) {
|
||||
std::ofstream defaultConfig("config.json", std::ios::out);
|
||||
config.configJsonRoot["IP Version"] = AF_INET6;
|
||||
config.configJsonRoot["IP"] = "::1";
|
||||
config.configJsonRoot["Port"] = 9010;
|
||||
config.configJsonRoot["LogLevel"] = 1;
|
||||
config.configJsonRoot["LogfileName"] = "log.log";
|
||||
config.configJsonRoot["LogfileSize"] = UINT32_MAX;
|
||||
config.configJsonRoot["LogfileCount"] = 5;
|
||||
config.configJsonRoot["PlayerID"] = 0;
|
||||
defaultConfig << config.configJsonRoot;
|
||||
defaultConfig.close();
|
||||
spdlog::critical(
|
||||
"\"config.json\" is missing. Default configuration has been written.");
|
||||
}
|
||||
try {
|
||||
if (configfile.is_open()) configfile >> config.configJsonRoot;
|
||||
|
||||
config.ipVersion = config.configJsonRoot["IP Version"].asInt();
|
||||
if (config.ipVersion != AF_INET && config.ipVersion != AF_INET6)
|
||||
throw std::runtime_error("Invalid IP Version.");
|
||||
|
||||
config.IP = config.configJsonRoot["IP"].asCString();
|
||||
|
||||
config.Port = config.configJsonRoot["Port"].asInt();
|
||||
if (config.Port < 0 || config.Port > 65535)
|
||||
throw std::runtime_error("Invalid listen port.");
|
||||
|
||||
int ll_ = config.configJsonRoot["LogLevel"].asInt();
|
||||
if (ll_ >= 0 && ll_ < spdlog::level::n_levels)
|
||||
config.logLevel = (spdlog::level::level_enum)ll_;
|
||||
else
|
||||
throw std::runtime_error("Invalid log level.");
|
||||
|
||||
config.logFileName = config.configJsonRoot["LogfileName"].asCString();
|
||||
config.logfileSize = config.configJsonRoot["LogfileSize"].asUInt();
|
||||
config.logfileCount = config.configJsonRoot["LogfileCount"].asUInt();
|
||||
|
||||
config.playerid = config.configJsonRoot["PlayerID"].asUInt64();
|
||||
} catch (Json::RuntimeError e) {
|
||||
spdlog::critical(
|
||||
std::string(std::string("[Json Error: ]") + e.what()).c_str());
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
} // namespace Chattr
|
||||
@@ -6,20 +6,19 @@
|
||||
#include "socket/tcp_socket.h"
|
||||
#include "socket/udp_socket.h"
|
||||
#include "socket/wsa_manager.h"
|
||||
#include "utils/ConfigManager.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/snowflake.h"
|
||||
#include "utils/utils.h"
|
||||
#include "vulkan_engine/asset/object/model.h"
|
||||
#include "vulkan_engine/vulkan/physics.h"
|
||||
|
||||
#define LISTENIP "::"
|
||||
#define LISTENPORT 9010
|
||||
#define TICKRATE 60
|
||||
#define TICKRATE 30
|
||||
constexpr double TICKDELAY = (1 / TICKRATE);
|
||||
|
||||
std::uint8_t CLIENTID = 0;
|
||||
|
||||
std::unordered_map<utils::Snowflake, veng::Model> MODELS;
|
||||
std::unordered_map<utils::Snowflake, std::shared_ptr<veng::Model>> MODELS;
|
||||
std::mutex MODELS_MUTEX;
|
||||
std::list<std::shared_ptr<Network::Socket>> CLIENTS;
|
||||
std::mutex CLIENTS_MUTEX;
|
||||
@@ -49,11 +48,26 @@ void EchoClient(utils::ThreadPool* tp, Network::IOCP* iocp,
|
||||
auto ID = model.ID;
|
||||
if (MODELS.find(ID) == MODELS.end()) {
|
||||
spdlog::info("model received: {}:{}", model.name, ID.snowflake);
|
||||
MODELS[ID] = std::move(model);
|
||||
MODELS[ID] = std::make_shared<veng::Model>();
|
||||
MODELS[ID]->Deserialize(recv_data);
|
||||
MODELS[ID]->OnColision = [](utils::ThreadPool* thread_pool,
|
||||
std::shared_ptr<veng::Model> self,
|
||||
std::shared_ptr<veng::Model> other) {
|
||||
if (self->shouldBeDestroyed || other->shouldBeDestroyed) return;
|
||||
spdlog::info("[{}:{}] and [{}:{}] is nearby.", self->name,
|
||||
self->ID.snowflake, other->name, other->ID.snowflake);
|
||||
|
||||
other->colision = false;
|
||||
other->visible = false;
|
||||
other->shouldBeDestroyed = true;
|
||||
self->colision = false;
|
||||
self->visible = false;
|
||||
self->shouldBeDestroyed = true;
|
||||
};
|
||||
} else {
|
||||
MODELS[ID].Deserialize(recv_data);
|
||||
MODELS[ID]->Deserialize(recv_data);
|
||||
}
|
||||
MODELS[ID].needsUpdate = true;
|
||||
MODELS[ID]->needsUpdate = true;
|
||||
} break;
|
||||
default:
|
||||
spdlog::error("unknown data type");
|
||||
@@ -74,20 +88,19 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
|
||||
auto delta_time = current_time - last_frame_time_;
|
||||
last_frame_time_ = current_time;
|
||||
|
||||
CLIENTS_MUTEX.lock();
|
||||
std::lock_guard client_lock(CLIENTS_MUTEX);
|
||||
for (auto it = CLIENTS.begin(); it != CLIENTS.end();) {
|
||||
if (*it == nullptr || it->get()->sock == 0) {
|
||||
if (*it == nullptr || it->get()->sock == 0)
|
||||
it = CLIENTS.erase(it);
|
||||
} else {
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
CLIENTS_MUTEX.unlock();
|
||||
|
||||
std::lock_guard model_lock(MODELS_MUTEX);
|
||||
for (auto it = MODELS.begin(); it != MODELS.end();) {
|
||||
auto& model = it->second;
|
||||
|
||||
if (model.shouldBeDestroyed) {
|
||||
if (model->shouldBeDestroyed) {
|
||||
it = MODELS.erase(it);
|
||||
continue;
|
||||
}
|
||||
@@ -97,33 +110,33 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
|
||||
for (auto it = MODELS.begin(); it != MODELS.end();) {
|
||||
auto& model = it->second;
|
||||
|
||||
if (std::abs(model.lifespan + 1.f) <
|
||||
if (std::abs(model->lifespan + 1.f) <
|
||||
std::numeric_limits<float>::epsilon()) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (model.lifespan <= 0.f) {
|
||||
it->second.shouldBeDestroyed = true;
|
||||
if (model->lifespan <= 0.f) {
|
||||
it->second->shouldBeDestroyed = true;
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
model.lifespan -= delta_time;
|
||||
model->lifespan -= delta_time;
|
||||
++it;
|
||||
}
|
||||
|
||||
CLIENTS_MUTEX.lock();
|
||||
for (auto& model : MODELS) {
|
||||
if (model.second.name == "camera_lag") continue;
|
||||
model.second.Update(delta_time);
|
||||
if (model.second->name == "camera_lag") continue;
|
||||
model.second->Update(delta_time);
|
||||
veng::Physics::invokeOnColisionEvent(tp, MODELS);
|
||||
for (auto& client : CLIENTS) {
|
||||
if (client->sock == 0) continue;
|
||||
std::vector<char> send_data;
|
||||
auto model_serialized = model.second.Serialize();
|
||||
auto model_serialized = model.second->Serialize();
|
||||
Packet::Header header;
|
||||
|
||||
if (model.second.shouldBeDestroyed) {
|
||||
if (model.second->shouldBeDestroyed) {
|
||||
header.opcode = Packet::Opcode::DESPAWNMODEL;
|
||||
} else {
|
||||
header.opcode = Packet::Opcode::UPDATEMODEL;
|
||||
@@ -136,11 +149,11 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
|
||||
header_serialized.end());
|
||||
send_data.insert(send_data.end(), model_serialized.begin(),
|
||||
model_serialized.end());
|
||||
if (!model.second.needsUpdate && !needs_all_update &&
|
||||
!model.second.shouldBeDestroyed) {
|
||||
if (!model.second->needsUpdate && !needs_all_update &&
|
||||
!model.second->shouldBeDestroyed) {
|
||||
continue;
|
||||
}
|
||||
model.second.needsUpdate = false;
|
||||
model.second->needsUpdate = false;
|
||||
if (iocp->send(client, send_data) == -1) {
|
||||
client->sock = 0;
|
||||
}
|
||||
@@ -148,7 +161,6 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
|
||||
// model.second.ID.snowflake);
|
||||
}
|
||||
}
|
||||
CLIENTS_MUTEX.unlock();
|
||||
|
||||
tp->enqueueJob(ClientRefresher, iocp);
|
||||
}
|
||||
@@ -156,21 +168,20 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
|
||||
int main(int argc, char* argv[]) {
|
||||
Network::WSAManager wsamanager;
|
||||
const veng::GlfwInitialization _glfw;
|
||||
#if !defined(NDEBUG)
|
||||
utils::setDefaultLogger(spdlog::level::level_enum::debug, "log.log",
|
||||
1024 * 1024, 2);
|
||||
#endif
|
||||
utils::Config config = utils::ConfigManager::load();
|
||||
utils::setDefaultLogger(config.logLevel, config.logFileName,
|
||||
config.logfileSize, config.logfileCount);
|
||||
|
||||
utils::ThreadPool tp(0);
|
||||
Network::IOCP iocp;
|
||||
iocp.init(&tp, SessionProtocol::TCP);
|
||||
|
||||
Network::Address addr;
|
||||
|
||||
addr.set(AF_INET6, "::", 9010);
|
||||
addr.set(config.ipVersion, config.IP, config.Port);
|
||||
|
||||
std::shared_ptr<Network::TCPSocket> TCPSock =
|
||||
std::make_shared<Network::TCPSocket>();
|
||||
TCPSock->init(AF_INET6);
|
||||
std::make_shared<Network::TCPSocket>(config.ipVersion);
|
||||
if (TCPSock->bind(addr) == INVALID_SOCKET) {
|
||||
spdlog::error("bind()");
|
||||
std::exit(EXIT_FAILURE);
|
||||
|
||||
57
Server/src/utils/ConfigManager.cpp
Normal file
57
Server/src/utils/ConfigManager.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "utils/ConfigManager.h"
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
Config ConfigManager::load() {
|
||||
Config config;
|
||||
|
||||
std::ifstream configfile("config.json", std::ifstream::binary);
|
||||
if (!configfile.is_open()) {
|
||||
std::ofstream defaultConfig("config.json", std::ios::out);
|
||||
config.configJsonRoot["IP Version"] = AF_INET6;
|
||||
config.configJsonRoot["IP"] = "::1";
|
||||
config.configJsonRoot["Port"] = 9010;
|
||||
config.configJsonRoot["LogLevel"] = 1;
|
||||
config.configJsonRoot["LogfileName"] = "log.log";
|
||||
config.configJsonRoot["LogfileSize"] = UINT32_MAX;
|
||||
config.configJsonRoot["LogfileCount"] = 5;
|
||||
defaultConfig << config.configJsonRoot;
|
||||
defaultConfig.close();
|
||||
spdlog::critical(
|
||||
"\"config.json\" is missing. Default configuration has been written.");
|
||||
}
|
||||
try {
|
||||
if (configfile.is_open()) configfile >> config.configJsonRoot;
|
||||
|
||||
config.ipVersion = config.configJsonRoot["IP Version"].asInt();
|
||||
if (config.ipVersion != AF_INET && config.ipVersion != AF_INET6)
|
||||
throw std::runtime_error("Invalid IP Version.");
|
||||
|
||||
config.IP = config.configJsonRoot["IP"].asCString();
|
||||
|
||||
config.Port = config.configJsonRoot["Port"].asInt();
|
||||
if (config.Port < 0 || config.Port > 65535)
|
||||
throw std::runtime_error("Invalid listen port.");
|
||||
|
||||
int ll_ = config.configJsonRoot["LogLevel"].asInt();
|
||||
if (ll_ >= 0 && ll_ < spdlog::level::n_levels)
|
||||
config.logLevel = (spdlog::level::level_enum)ll_;
|
||||
else
|
||||
throw std::runtime_error("Invalid log level.");
|
||||
|
||||
config.logFileName = config.configJsonRoot["LogfileName"].asCString();
|
||||
config.logfileSize = config.configJsonRoot["LogfileSize"].asUInt();
|
||||
config.logfileCount = config.configJsonRoot["LogfileCount"].asUInt();
|
||||
} catch (Json::RuntimeError e) {
|
||||
spdlog::critical(
|
||||
std::string(std::string("[Json Error: ]") + e.what()).c_str());
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
} // namespace Chattr
|
||||
@@ -14,9 +14,8 @@ Session::Session(gsl::not_null<Network::IOCP*> iocp, utils::ThreadPool* tp,
|
||||
case SessionProtocol::QUIC:
|
||||
case SessionProtocol::TCP:
|
||||
case SessionProtocol::TLS: {
|
||||
Network::TCPSocket* sock = new Network::TCPSocket();
|
||||
Network::TCPSocket* sock = new Network::TCPSocket(addr.family);
|
||||
sock_ = sock;
|
||||
sock->init(addr.family);
|
||||
switch (type) {
|
||||
case SessionType::CONNECT:
|
||||
sock->connect(addr);
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace Network {
|
||||
|
||||
Socket::Socket() {
|
||||
init(AF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
|
||||
Socket::Socket(int domain, int type, int protocol) {
|
||||
init(domain, type, protocol);
|
||||
}
|
||||
@@ -61,6 +65,8 @@ int Socket::bind(Address __addr) {
|
||||
bindAddr = __addr;
|
||||
int retVal = ::bind(sock, &__addr.addr, __addr.length);
|
||||
if (retVal == INVALID_SOCKET) {
|
||||
int err = WSAGetLastError();
|
||||
spdlog::error("bind() failed: WSA error {} (0x{:X})", err, err);
|
||||
spdlog::critical("bind()");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Network {
|
||||
|
||||
TCPSocket::TCPSocket(int domain) { init(domain); }
|
||||
|
||||
int TCPSocket::init(int domain) { return init(domain, SOCK_STREAM, 0); }
|
||||
|
||||
int TCPSocket::listen(int __n) {
|
||||
|
||||
16
impl/utils/ConfigManager.cpp
Normal file
16
impl/utils/ConfigManager.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "Utils/ConfigManager.h"
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace utils {
|
||||
void ConfigManager::save(Config& config) {
|
||||
|
||||
std::ofstream configfile("config.json", std::ios::out);
|
||||
|
||||
configfile << config.configJsonRoot;
|
||||
|
||||
configfile.close();
|
||||
}
|
||||
} // namespace utils
|
||||
@@ -55,6 +55,9 @@ std::vector<char> Model::Serialize() {
|
||||
Append(buffer, scale);
|
||||
|
||||
Append(buffer, original_offset);
|
||||
|
||||
Append(buffer, OwnerID);
|
||||
|
||||
Append(buffer, radius);
|
||||
Append(buffer, lifespan);
|
||||
|
||||
@@ -84,6 +87,9 @@ void Model::Deserialize(std::vector<char> data) {
|
||||
Read(data, offset, scale);
|
||||
|
||||
Read(data, offset, original_offset);
|
||||
|
||||
Read(data, offset, OwnerID);
|
||||
|
||||
Read(data, offset, radius);
|
||||
Read(data, offset, lifespan);
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ void Engine::Update() {
|
||||
vulkan_graphics->RenderModel(it.second);
|
||||
}
|
||||
|
||||
Physics::invokeOnColisionEvent(thread_pool_, models_);
|
||||
// Physics::invokeOnColisionEvent(thread_pool_, models_);
|
||||
|
||||
vulkan_graphics->EndFrame();
|
||||
}
|
||||
@@ -187,38 +187,90 @@ float GetAlpha(double old_time, double new_time) {
|
||||
|
||||
void Interpolation(Packet::Header header, std::shared_ptr<veng::Model> local,
|
||||
std::shared_ptr<veng::Model> remote) {
|
||||
constexpr float position_threshold = 5.0f; // 위치 차이 임계값
|
||||
constexpr float rotation_threshold = 0.5f; // 회전 차이 임계값 (라디안 기준)
|
||||
|
||||
std::lock_guard lock(local->modding);
|
||||
local->position =
|
||||
glm::mix(local->position, remote->position,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
local->linear_velocity =
|
||||
glm::mix(local->linear_velocity, remote->linear_velocity,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
float alpha = GetAlpha(local->lastUpdatedTime, header.timestamp);
|
||||
|
||||
// 위치 보간 또는 강제 이동
|
||||
if (glm::distance(local->position, remote->position) > position_threshold) {
|
||||
local->position = remote->position;
|
||||
} else {
|
||||
local->position = glm::mix(local->position, remote->position, alpha);
|
||||
}
|
||||
|
||||
// 선속도
|
||||
if (glm::length(remote->linear_velocity - local->linear_velocity) >
|
||||
position_threshold) {
|
||||
local->linear_velocity = remote->linear_velocity;
|
||||
} else {
|
||||
local->linear_velocity =
|
||||
glm::mix(local->linear_velocity, remote->linear_velocity, alpha);
|
||||
}
|
||||
|
||||
local->linear_acceleration =
|
||||
glm::mix(local->linear_acceleration, remote->linear_acceleration,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
glm::mix(local->linear_acceleration, remote->linear_acceleration, alpha);
|
||||
|
||||
// 회전 보간 또는 강제 이동
|
||||
if (glm::length(remote->rotation - local->rotation) > rotation_threshold) {
|
||||
local->rotation = remote->rotation;
|
||||
} else {
|
||||
local->rotation = glm::mix(local->rotation, remote->rotation, alpha);
|
||||
}
|
||||
|
||||
local->rotation =
|
||||
glm::mix(local->rotation, remote->rotation,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
local->angular_velocity =
|
||||
glm::mix(local->angular_velocity, remote->angular_velocity,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
local->angular_acceleration =
|
||||
glm::mix(local->angular_acceleration, remote->angular_acceleration,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
glm::mix(local->angular_velocity, remote->angular_velocity, alpha);
|
||||
|
||||
local->scale = glm::mix(local->scale, remote->scale,
|
||||
GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
local->angular_acceleration = glm::mix(local->angular_acceleration,
|
||||
remote->angular_acceleration, alpha);
|
||||
|
||||
// 스케일은 보간만 적용
|
||||
local->scale = glm::mix(local->scale, remote->scale, alpha);
|
||||
|
||||
// 동기화 항목은 그대로 적용
|
||||
local->original_offset = remote->original_offset;
|
||||
local->radius = remote->radius;
|
||||
local->lifespan = remote->lifespan;
|
||||
|
||||
local->visible = remote->visible;
|
||||
local->colision = remote->colision;
|
||||
}
|
||||
|
||||
|
||||
//void Interpolation(Packet::Header header, std::shared_ptr<veng::Model> local,
|
||||
// std::shared_ptr<veng::Model> remote) {
|
||||
// std::lock_guard lock(local->modding);
|
||||
// local->position =
|
||||
// glm::mix(local->position, remote->position,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
// local->linear_velocity =
|
||||
// glm::mix(local->linear_velocity, remote->linear_velocity,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
// local->linear_acceleration =
|
||||
// glm::mix(local->linear_acceleration, remote->linear_acceleration,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
//
|
||||
// local->rotation =
|
||||
// glm::mix(local->rotation, remote->rotation,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
// local->angular_velocity =
|
||||
// glm::mix(local->angular_velocity, remote->angular_velocity,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
// local->angular_acceleration =
|
||||
// glm::mix(local->angular_acceleration, remote->angular_acceleration,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
//
|
||||
// local->scale = glm::mix(local->scale, remote->scale,
|
||||
// GetAlpha(local->lastUpdatedTime, header.timestamp));
|
||||
//
|
||||
// local->original_offset = remote->original_offset;
|
||||
// local->radius = remote->radius;
|
||||
// local->lifespan = remote->lifespan;
|
||||
//
|
||||
// local->visible = remote->visible;
|
||||
// local->colision = remote->colision;
|
||||
//}
|
||||
|
||||
void Engine::ResponseToServerAndRefresh(std::shared_ptr<Network::Socket> sock) {
|
||||
if (sock->sock == 0) return;
|
||||
|
||||
|
||||
@@ -38,33 +38,31 @@ void Physics::invokeOnColisionEvent(
|
||||
|
||||
void Physics::invokeOnColisionEvent(
|
||||
gsl::not_null<utils::ThreadPool*> thread_pool,
|
||||
std::unordered_map<utils::Snowflake, Model>& models) {
|
||||
std::unordered_map<utils::Snowflake, std::shared_ptr<Model>>& models) {
|
||||
constexpr std::float_t EPSILON = std::numeric_limits<std::float_t>::epsilon();
|
||||
|
||||
for (std::unordered_map<utils::Snowflake, Model>::iterator
|
||||
for (std::unordered_map<utils::Snowflake, std::shared_ptr<Model>>::iterator
|
||||
iter_A = models.begin();
|
||||
iter_A != models.end(); iter_A++) {
|
||||
for (auto iter_B = std::next(iter_A); iter_B != models.end(); iter_B++) {
|
||||
auto& model_A = iter_A->second;
|
||||
std::lock_guard<std::mutex> Alock(model_A.modding);
|
||||
auto& model_B = iter_B->second;
|
||||
std::lock_guard<std::mutex> Block(model_B.modding);
|
||||
if (!model_A.colision || !model_B.colision) continue;
|
||||
auto model_A = iter_A->second;
|
||||
std::lock_guard<std::mutex> Alock(model_A->modding);
|
||||
auto model_B = iter_B->second;
|
||||
std::lock_guard<std::mutex> Block(model_B->modding);
|
||||
if (!model_A->colision || !model_B->colision) continue;
|
||||
std::float_t distance =
|
||||
glm::distance(model_A.position, model_B.position);
|
||||
std::float_t modelA_radius = model_A.radius * model_A.scale.x;
|
||||
std::float_t modelB_radius = model_B.radius * model_B.scale.x;
|
||||
glm::distance(model_A->position, model_B->position);
|
||||
std::float_t modelA_radius = model_A->radius * model_A->scale.x;
|
||||
std::float_t modelB_radius = model_B->radius * model_B->scale.x;
|
||||
if (distance <= modelA_radius + modelB_radius) {
|
||||
if (model_A.OnColision)
|
||||
thread_pool->enqueueJob(model_A.OnColision,
|
||||
std::make_shared<Model>(std::move(model_A)),
|
||||
std::make_shared<Model>(std::move(model_B)));
|
||||
/*model_A = iter_A->second;
|
||||
model_B = iter_B->second;*/
|
||||
if (model_B.OnColision)
|
||||
thread_pool->enqueueJob(model_B.OnColision,
|
||||
std::make_shared<Model>(std::move(model_B)),
|
||||
std::make_shared<Model>(std::move(model_A)));
|
||||
model_A = iter_A->second;
|
||||
model_B = iter_B->second;
|
||||
if (model_A->OnColision)
|
||||
thread_pool->enqueueJob(model_A->OnColision, model_A, model_B);
|
||||
model_A = iter_A->second;
|
||||
model_B = iter_B->second;
|
||||
if (model_B->OnColision)
|
||||
thread_pool->enqueueJob(model_B->OnColision, model_A, model_B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ struct Address;
|
||||
|
||||
class Socket {
|
||||
public:
|
||||
Socket() = default;
|
||||
Socket();
|
||||
Socket(int domain, int type, int protocol);
|
||||
~Socket();
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ class TCPSocket : public Socket {
|
||||
public:
|
||||
using Socket::init;
|
||||
using Socket::Socket;
|
||||
TCPSocket(int domain);
|
||||
|
||||
int init(int domain);
|
||||
int listen(int __n);
|
||||
void accept(std::shared_ptr<TCPSocket>& newSock, Address& addr);
|
||||
|
||||
29
include/utils/ConfigManager.h
Normal file
29
include/utils/ConfigManager.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <json/json.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace utils {
|
||||
|
||||
struct Config;
|
||||
|
||||
class ConfigManager {
|
||||
public:
|
||||
static Config load();
|
||||
static void save(Config&);
|
||||
};
|
||||
|
||||
struct Config {
|
||||
~Config() { ConfigManager::save(*this); }
|
||||
Json::Value configJsonRoot;
|
||||
std::uint32_t ipVersion = 0;
|
||||
gsl::czstring IP = "";
|
||||
std::uint32_t Port = 0;
|
||||
spdlog::level::level_enum logLevel = spdlog::level::off;
|
||||
gsl::czstring logFileName = "";
|
||||
std::uint32_t logfileSize = 0;
|
||||
std::uint32_t logfileCount = 0;
|
||||
std::uint64_t playerid = 0;
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
@@ -103,6 +103,7 @@ struct Model {
|
||||
material = std::move(other.material);
|
||||
original_offset = other.original_offset;
|
||||
owner = other.owner;
|
||||
OwnerID = ID;
|
||||
radius = other.radius;
|
||||
lifespan = other.lifespan;
|
||||
OnColision = other.OnColision;
|
||||
@@ -148,6 +149,7 @@ struct Model {
|
||||
glm::vec3 original_offset = glm::vec3(0.f);
|
||||
|
||||
std::weak_ptr<Model> owner;
|
||||
utils::Snowflake OwnerID;
|
||||
|
||||
std::float_t radius = 0.f;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class Physics {
|
||||
std::unordered_map<std::string, std::shared_ptr<Model>>& models);
|
||||
static void invokeOnColisionEvent(
|
||||
gsl::not_null<utils::ThreadPool*> thread_pool,
|
||||
std::unordered_map<utils::Snowflake, Model>& models);
|
||||
std::unordered_map<utils::Snowflake, std::shared_ptr<Model>>& models);
|
||||
|
||||
bool RayTrace(const glm::vec3& rayOrigin, const glm::vec3& rayDir,
|
||||
const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2,
|
||||
|
||||
Reference in New Issue
Block a user