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