일단 이제 자잘한 버그만 고치면 될 듯?
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -81,6 +81,9 @@
|
|||||||
"expected": "cpp",
|
"expected": "cpp",
|
||||||
"complex": "cpp",
|
"complex": "cpp",
|
||||||
"__config": "cpp",
|
"__config": "cpp",
|
||||||
"ranges": "cpp"
|
"ranges": "cpp",
|
||||||
|
"valarray": "cpp",
|
||||||
|
"__tree": "cpp",
|
||||||
|
"map": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,7 @@ FetchContent_MakeAvailable(JSONCPP)
|
|||||||
|
|
||||||
file(GLOB_RECURSE additional_sources CONFIGURE_DEPENDS
|
file(GLOB_RECURSE additional_sources CONFIGURE_DEPENDS
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../impl/*.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../impl/*.cpp"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME}
|
||||||
|
|||||||
101
Client/include/ClientManager/ClientManager.hpp
Normal file
101
Client/include/ClientManager/ClientManager.hpp
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Utils/ThreadPool.hpp"
|
||||||
|
#include "Utils/ConfigManager.hpp"
|
||||||
|
#include "Socket/IOCP.hpp"
|
||||||
|
#include "Packet/Packet.hpp"
|
||||||
|
|
||||||
|
namespace Chattr {
|
||||||
|
|
||||||
|
class ClientManager {
|
||||||
|
public:
|
||||||
|
void _IOCPClient(ThreadPool* thread, IOCPPASSINDATA* data);
|
||||||
|
|
||||||
|
PacketSet packetParser(Packet Packet);
|
||||||
|
|
||||||
|
template<typename _Callable>
|
||||||
|
void init(_Callable _IOCPClient) {
|
||||||
|
auto config = ConfigManager::load();
|
||||||
|
log::setDefaultLogger(config.logLevel, config.logFileName, config.logfileSize, config.logfileCount);
|
||||||
|
threadPool_.init(0);
|
||||||
|
iocp_.init(&threadPool_, _IOCPClient);
|
||||||
|
|
||||||
|
struct Address serveraddr;
|
||||||
|
if (config.ipVersion == 4) {
|
||||||
|
sock_.init(AF_INET);
|
||||||
|
serveraddr.set(AF_INET, config.IP, config.Port);
|
||||||
|
}
|
||||||
|
else if (config.ipVersion == 6) {
|
||||||
|
sock_.init(AF_INET6);
|
||||||
|
serveraddr.set(AF_INET6, config.IP, config.Port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock_.connect(serveraddr) == INVALID_SOCKET) {
|
||||||
|
spdlog::error("{}", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_ = new IOCPPASSINDATA;
|
||||||
|
::memset(&data_->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
data_->socket = std::make_shared<TCPSocket>(std::move(sock_));
|
||||||
|
data_->recvbytes = data_->sendbytes = 0;
|
||||||
|
data_->wsabuf.buf = data_->buf;
|
||||||
|
data_->wsabuf.len = 1500;
|
||||||
|
data_->IOCPInstance = &iocp_;
|
||||||
|
iocp_.registerSocket(data_);
|
||||||
|
|
||||||
|
spdlog::info("Connection established from [{}]", (std::string)serveraddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
init([this](ThreadPool* thread, IOCPPASSINDATA* data) {
|
||||||
|
this->_IOCPClient(thread, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void processresponsePacket(ResponsePacket responsePacket, IOCPPASSINDATA* data);
|
||||||
|
void processRoomCreateResponsePacket(RoomCreateResponsePacket roomCreateResponsePacket, IOCPPASSINDATA* data);
|
||||||
|
void processRoomListResponse(RoomListResponsePacket roomListResponsePacket, IOCPPASSINDATA* data);
|
||||||
|
void processRoomJoinResponsePacket(RoomJoinResponsePacket roomJoinResponsePacket, IOCPPASSINDATA* data);
|
||||||
|
void processRoomExitResponsePacket(RoomExitResponsePacket roomExitResponsePacket, IOCPPASSINDATA* data);
|
||||||
|
void processUsersListResponsePacket(UsersListResponsePacket usersListResponsePacket, IOCPPASSINDATA* data);
|
||||||
|
void processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data);
|
||||||
|
void processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data);
|
||||||
|
|
||||||
|
void registerUser(std::string userName);
|
||||||
|
void deleteUser(Snowflake UID);
|
||||||
|
std::vector<std::pair<Snowflake, std::string>> getUserList();
|
||||||
|
|
||||||
|
Snowflake createRoom(std::string roomName);
|
||||||
|
void deleteRoom(Snowflake RID);
|
||||||
|
std::vector<std::pair<Snowflake, std::string>> getRoomList();
|
||||||
|
|
||||||
|
void joinRoom(Snowflake UID, Snowflake RID);
|
||||||
|
void exitRoom(Snowflake UID, Snowflake RID);
|
||||||
|
|
||||||
|
void run();
|
||||||
|
private:
|
||||||
|
ThreadPool threadPool_;
|
||||||
|
IOCP iocp_;
|
||||||
|
|
||||||
|
Snowflake myID_;
|
||||||
|
Snowflake myRoomID_;
|
||||||
|
|
||||||
|
IOCPPASSINDATA* data_;
|
||||||
|
|
||||||
|
bool inRoom_ = false;
|
||||||
|
|
||||||
|
TCPSocket sock_;
|
||||||
|
|
||||||
|
std::mutex resourceMutex_;
|
||||||
|
|
||||||
|
std::unordered_map<Snowflake, std::string> roomNames_;
|
||||||
|
|
||||||
|
std::unordered_map<Snowflake, std::unordered_map<Snowflake, std::shared_ptr<TCPSocket>>> rooms_;
|
||||||
|
|
||||||
|
std::unordered_map<Snowflake, std::shared_ptr<TCPSocket>> UID2userSocket_;
|
||||||
|
std::unordered_map<std::shared_ptr<TCPSocket>, Snowflake> userSocket2UID_;
|
||||||
|
|
||||||
|
std::unordered_map<Snowflake, std::string> userNames_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
488
Client/src/ClientManager/ClientManager.cpp
Normal file
488
Client/src/ClientManager/ClientManager.cpp
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
#include "ClientManager/ClientManager.hpp"
|
||||||
|
#include "Utils/ConfigManager.hpp"
|
||||||
|
#include "Utils/StringTokenizer.hpp"
|
||||||
|
#include "Socket/Log.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Chattr {
|
||||||
|
|
||||||
|
void ClientManager::_IOCPClient(Chattr::ThreadPool* thread, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
Chattr::Packet pack;
|
||||||
|
int packetSize = data->transferredbytes;
|
||||||
|
|
||||||
|
if (data->event == IOCPEVENT::WRITE && data->transferredbytes >= data->wsabuf.len) {
|
||||||
|
data->event = IOCPEVENT::READ;
|
||||||
|
data->wsabuf.len = 1500;
|
||||||
|
data->IOCPInstance->recv(data, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pack.serialized, data->wsabuf.buf, data->wsabuf.len);
|
||||||
|
|
||||||
|
std::uint16_t packetLength = ::ntohs(pack.__data.packetLength);
|
||||||
|
|
||||||
|
if (data->event == IOCPEVENT::READ && data->transferredbytes < packetLength + 8) {
|
||||||
|
data->IOCPInstance->recv(data, 1);
|
||||||
|
data->wsabuf.len = 1500;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pack.convToH();
|
||||||
|
PacketSet packetSet = packetParser(pack);
|
||||||
|
pack.convToN();
|
||||||
|
switch (packetSet) {
|
||||||
|
case PacketSet::LOGINRESPONSE:
|
||||||
|
case PacketSet::ROOMCREATERESPONSE:
|
||||||
|
case PacketSet::ROOMLISTRESPONSE:
|
||||||
|
case PacketSet::ROOMJOINRESPONSE:
|
||||||
|
case PacketSet::ROOMEXITRESPONSE:
|
||||||
|
case PacketSet::USERSLISTRESPONSE:
|
||||||
|
case PacketSet::RESPONSE: {
|
||||||
|
ResponsePacket responsePacket;
|
||||||
|
std::memcpy(&responsePacket.serialized, &pack.serialized, 8 + packetLength);
|
||||||
|
responsePacket.convToH();
|
||||||
|
processresponsePacket(responsePacket, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketSet::DATAPOST: {
|
||||||
|
DataPostPacket dataPostPacket;
|
||||||
|
std::memcpy(&dataPostPacket.serialized, &pack.serialized, 8 + packetLength);
|
||||||
|
dataPostPacket.convToH();
|
||||||
|
processDataPostPacket(dataPostPacket, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketSet::CONTINUE: {
|
||||||
|
ContinuePacket continuePacket;
|
||||||
|
std::memcpy(&continuePacket.serialized, &pack.serialized, 8 + packetLength);
|
||||||
|
continuePacket.convToH();
|
||||||
|
processContinuePacket(continuePacket, data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketSet::INVALID:
|
||||||
|
default: {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketSet ClientManager::packetParser(Packet Packet) {
|
||||||
|
if (Packet.__data.packetLength < 0 || Packet.__data.packetLength > 1492)
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
|
||||||
|
switch (Packet.__data.packetType) {
|
||||||
|
case PacketCategory::PACKET_POST:
|
||||||
|
if (Packet.__data.requestType != RequestType::DATA) {
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
}
|
||||||
|
switch (Packet.__data.dataType) {
|
||||||
|
case DataType::TEXT:
|
||||||
|
case DataType::BINARY:
|
||||||
|
return PacketSet::DATAPOST;
|
||||||
|
default:
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketCategory::PACKET_REQUEST:
|
||||||
|
switch (Packet.__data.requestType) {
|
||||||
|
case RequestType::LOGIN:
|
||||||
|
return PacketSet::LOGINREQUEST;
|
||||||
|
case RequestType::ROOM_CREATE:
|
||||||
|
return PacketSet::ROOMCREATEREQUEST;
|
||||||
|
case RequestType::ROOM_LIST:
|
||||||
|
return PacketSet::ROOMLISTREQUEST;
|
||||||
|
case RequestType::ROOM_JOIN:
|
||||||
|
return PacketSet::ROOMJOINREQUEST;
|
||||||
|
case RequestType::ROOM_EXIT:
|
||||||
|
return PacketSet::ROOMEXITREQUEST;
|
||||||
|
case RequestType::USERS_LIST:
|
||||||
|
return PacketSet::USERSLISTREQUEST;
|
||||||
|
case RequestType::DATA:
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketCategory::PACKET_RESPONSE:
|
||||||
|
switch (Packet.__data.requestType) {
|
||||||
|
case RequestType::LOGIN:
|
||||||
|
return PacketSet::LOGINRESPONSE;
|
||||||
|
case RequestType::ROOM_CREATE:
|
||||||
|
return PacketSet::ROOMCREATERESPONSE;
|
||||||
|
case RequestType::ROOM_LIST:
|
||||||
|
return PacketSet::ROOMLISTRESPONSE;
|
||||||
|
case RequestType::ROOM_JOIN:
|
||||||
|
return PacketSet::ROOMJOINRESPONSE;
|
||||||
|
case RequestType::ROOM_EXIT:
|
||||||
|
return PacketSet::ROOMEXITRESPONSE;
|
||||||
|
case RequestType::USERS_LIST:
|
||||||
|
return PacketSet::USERSLISTRESPONSE;
|
||||||
|
case RequestType::DATA:
|
||||||
|
return PacketSet::RESPONSE;
|
||||||
|
default:
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketCategory::PACKET_CONTINUE:
|
||||||
|
return PacketSet::CONTINUE;
|
||||||
|
default:
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PacketSet::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processresponsePacket(ResponsePacket responsePacket, IOCPPASSINDATA* data) {
|
||||||
|
responsePacket;
|
||||||
|
// std::string userName(
|
||||||
|
// (char*)loginResponsePacket.__data.data,
|
||||||
|
// loginResponsePacket.__data.packetLength);
|
||||||
|
// registerUser(userName);
|
||||||
|
|
||||||
|
// LoginResponsePacket loginResponsePacket;
|
||||||
|
// loginResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
// loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN;
|
||||||
|
// loginResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
// loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake);
|
||||||
|
// loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
// Snowflake yourId = userSocket2UID_[data->socket];
|
||||||
|
// ::memcpy(loginResponsePacket.__data.yourId, &yourId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
// loginResponsePacket.convToN();
|
||||||
|
// memcpy(data->wsabuf.buf, loginResponsePacket.serialized, 18);
|
||||||
|
// data->sendbytes = 18;
|
||||||
|
// data->wsabuf.len = 18;
|
||||||
|
// data->IOCPInstance->send(data, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processRoomCreateResponsePacket(RoomCreateResponsePacket roomCreateResponsePacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
// std::string roomName(
|
||||||
|
// (char*)roomCreateResponsePacket.__data.data,
|
||||||
|
// roomCreateResponsePacket.__data.packetLength);
|
||||||
|
// Snowflake RID = createRoom(roomName);
|
||||||
|
|
||||||
|
// RoomCreateResponsePacket roomCreateResponsePacket;
|
||||||
|
// roomCreateResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
// roomCreateResponsePacket.__data.requestType = Chattr::RequestType::ROOM_CREATE;
|
||||||
|
// roomCreateResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
// roomCreateResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake);
|
||||||
|
// roomCreateResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
// ::memcpy(roomCreateResponsePacket.__data.createdRoomId, &RID, sizeof(Snowflake));
|
||||||
|
|
||||||
|
// roomCreateResponsePacket.convToN();
|
||||||
|
// memcpy(data->wsabuf.buf, roomCreateResponsePacket.serialized, 18);
|
||||||
|
// data->sendbytes = 18;
|
||||||
|
// data->wsabuf.len = 18;
|
||||||
|
// data->IOCPInstance->send(data, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processRoomListResponse(RoomListResponsePacket roomListResponsePacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
// auto roomsList = getRoomList();
|
||||||
|
|
||||||
|
// for (auto room : roomsList) {
|
||||||
|
// RoomListResponsePacket roomListResponsePacket;
|
||||||
|
// roomListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
// roomListResponsePacket.__data.requestType = Chattr::RequestType::ROOM_LIST;
|
||||||
|
// roomListResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
// roomListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + room.second.size();
|
||||||
|
// roomListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
// roomListResponsePacket.__data.roomCount = roomsList.size();
|
||||||
|
// ::memcpy(roomListResponsePacket.__data.roomId, &room.first, sizeof(Snowflake));
|
||||||
|
// ::memcpy(roomListResponsePacket.__data.name, room.second.c_str(), room.second.size());
|
||||||
|
|
||||||
|
// int packetLength = roomListResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
// Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA;
|
||||||
|
// ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
// ptr->socket = data->socket;
|
||||||
|
// ptr->recvbytes = ptr->sendbytes = 0;
|
||||||
|
// ptr->wsabuf.buf = ptr->buf;
|
||||||
|
// ptr->wsabuf.len = packetLength + 8;
|
||||||
|
// ptr->IOCPInstance = data->IOCPInstance;
|
||||||
|
|
||||||
|
// roomListResponsePacket.convToN();
|
||||||
|
// memcpy(ptr->wsabuf.buf, roomListResponsePacket.serialized, packetLength + 8);
|
||||||
|
// data->sendbytes = packetLength + 8;
|
||||||
|
// data->IOCPInstance->send(ptr, 1, 0);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processRoomJoinResponsePacket(RoomJoinResponsePacket roomJoinResponsePacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
// Snowflake myID, roomID;
|
||||||
|
// ::memcpy(&myID.snowflake, roomJoinResponsePacket.__data.myId, sizeof(Snowflake));
|
||||||
|
// ::memcpy(&roomID.snowflake, roomJoinResponsePacket.__data.roomId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
// joinRoom(myID, roomID);
|
||||||
|
|
||||||
|
// RoomJoinResponsePacket roomJoinResponsePacket;
|
||||||
|
// roomJoinResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
// roomJoinResponsePacket.__data.requestType = Chattr::RequestType::ROOM_JOIN;
|
||||||
|
// roomJoinResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
// roomJoinResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
// roomJoinResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
// int packetLength = roomJoinResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
// roomJoinResponsePacket.convToN();
|
||||||
|
// ::memcpy(data->wsabuf.buf, roomJoinResponsePacket.serialized, 10);
|
||||||
|
// data->sendbytes = 10;
|
||||||
|
// data->wsabuf.len = 10;
|
||||||
|
// data->IOCPInstance->send(data, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processRoomExitResponsePacket(RoomExitResponsePacket roomExitResponsePacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
// Snowflake myID, roomID;
|
||||||
|
// ::memcpy(&myID.snowflake, roomExitResponsePacket.__data.myId, sizeof(Snowflake));
|
||||||
|
// ::memcpy(&roomID.snowflake, roomExitResponsePacket.__data.roomId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
// exitRoom(myID, roomID);
|
||||||
|
|
||||||
|
// RoomExitResponsePacket roomExitResponsePacket;
|
||||||
|
// roomExitResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
// roomExitResponsePacket.__data.requestType = Chattr::RequestType::ROOM_EXIT;
|
||||||
|
// roomExitResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
// roomExitResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
// roomExitResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
// int packetLength = roomExitResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
// roomExitResponsePacket.convToN();
|
||||||
|
// ::memcpy(data->wsabuf.buf, roomExitResponsePacket.serialized, 10);
|
||||||
|
// data->sendbytes = 10;
|
||||||
|
// data->wsabuf.len = 10;
|
||||||
|
// data->IOCPInstance->send(data, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processUsersListResponsePacket(UsersListResponsePacket usersListResponsePacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
// auto usersList = getUserList();
|
||||||
|
|
||||||
|
// for (auto user : usersList) {
|
||||||
|
// UsersListResponsePacket usersListResponsePacket;
|
||||||
|
// usersListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
// usersListResponsePacket.__data.requestType = Chattr::RequestType::USERS_LIST;
|
||||||
|
// usersListResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
// usersListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + user.second.size();
|
||||||
|
// usersListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
// usersListResponsePacket.__data.usersCount = usersList.size();
|
||||||
|
// ::memcpy(usersListResponsePacket.__data.userId, &user.first, sizeof(Snowflake));
|
||||||
|
// ::memcpy(usersListResponsePacket.__data.name, user.second.c_str(), user.second.size());
|
||||||
|
|
||||||
|
// int packetLength = usersListResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
// Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA;
|
||||||
|
// ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
// ptr->socket = data->socket;
|
||||||
|
// ptr->recvbytes = ptr->sendbytes = 0;
|
||||||
|
// ptr->wsabuf.buf = ptr->buf;
|
||||||
|
// ptr->wsabuf.len = packetLength + 8;
|
||||||
|
// ptr->IOCPInstance = data->IOCPInstance;
|
||||||
|
|
||||||
|
// usersListResponsePacket.convToN();
|
||||||
|
// memcpy(ptr->wsabuf.buf, usersListResponsePacket.serialized, packetLength + 8);
|
||||||
|
// data->sendbytes = packetLength + 8;
|
||||||
|
// data->IOCPInstance->send(ptr, 1, 0);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data) {
|
||||||
|
Snowflake destID;
|
||||||
|
::memcpy(&destID.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<TCPSocket>> destinationSockets;
|
||||||
|
|
||||||
|
if (userNames_.find(destID) != userNames_.end())
|
||||||
|
destinationSockets.push_back(UID2userSocket_[destID]);
|
||||||
|
else
|
||||||
|
for (auto user : rooms_[destID])
|
||||||
|
destinationSockets.push_back(user.second);
|
||||||
|
|
||||||
|
spdlog::info("Received [{}] from : [{}] to : [{}]",
|
||||||
|
std::string((char*)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t) * 5)),
|
||||||
|
(std::string)data->socket->remoteAddr,
|
||||||
|
destID.snowflake);
|
||||||
|
|
||||||
|
ResponsePacket responsePacket;
|
||||||
|
responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
responsePacket.__data.requestType = Chattr::RequestType::DATA;
|
||||||
|
responsePacket.__data.dataType = Chattr::DataType::TEXT;
|
||||||
|
responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
responsePacket.convToN();
|
||||||
|
memcpy(data->wsabuf.buf, responsePacket.serialized, 10);
|
||||||
|
data->sendbytes = 10;
|
||||||
|
data->wsabuf.len = 10;
|
||||||
|
data->IOCPInstance->send(data, 1, 0);
|
||||||
|
|
||||||
|
int packetLength = dataPostPacket.__data.packetLength;
|
||||||
|
|
||||||
|
for (auto dest : destinationSockets) {
|
||||||
|
|
||||||
|
Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA;
|
||||||
|
::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
ptr->socket = dest;
|
||||||
|
ptr->recvbytes = ptr->sendbytes = 0;
|
||||||
|
ptr->wsabuf.buf = ptr->buf;
|
||||||
|
ptr->wsabuf.len = packetLength + 6;
|
||||||
|
ptr->IOCPInstance = data->IOCPInstance;
|
||||||
|
|
||||||
|
dataPostPacket.convToN();
|
||||||
|
memcpy(ptr->wsabuf.buf, dataPostPacket.serialized, packetLength + 6);
|
||||||
|
data->sendbytes = packetLength + 6;
|
||||||
|
data->IOCPInstance->send(ptr, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data) {
|
||||||
|
Snowflake destID;
|
||||||
|
::memcpy(&destID.snowflake, continuePacket.__data.destId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<TCPSocket>> destinationSockets;
|
||||||
|
|
||||||
|
if (userNames_.find(destID) != userNames_.end())
|
||||||
|
destinationSockets.push_back(UID2userSocket_[destID]);
|
||||||
|
else
|
||||||
|
for (auto user : rooms_[destID])
|
||||||
|
destinationSockets.push_back(user.second);
|
||||||
|
|
||||||
|
spdlog::info("Received [{}] from : [{}] to : [{}]",
|
||||||
|
std::string((char*)continuePacket.__data.data, continuePacket.__data.packetLength - (sizeof(std::uint16_t) * 5)),
|
||||||
|
(std::string)data->socket->remoteAddr,
|
||||||
|
destID.snowflake);
|
||||||
|
|
||||||
|
ResponsePacket responsePacket;
|
||||||
|
responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
responsePacket.__data.requestType = Chattr::RequestType::DATA;
|
||||||
|
responsePacket.__data.dataType = Chattr::DataType::TEXT;
|
||||||
|
responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
responsePacket.convToN();
|
||||||
|
memcpy(data->wsabuf.buf, responsePacket.serialized, 10);
|
||||||
|
data->sendbytes = 10;
|
||||||
|
data->wsabuf.len = 10;
|
||||||
|
data->IOCPInstance->send(data, 1, 0);
|
||||||
|
|
||||||
|
int packetLength = continuePacket.__data.packetLength;
|
||||||
|
|
||||||
|
for (auto dest : destinationSockets) {
|
||||||
|
Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA;
|
||||||
|
::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
ptr->socket = dest;
|
||||||
|
ptr->recvbytes = ptr->sendbytes = 0;
|
||||||
|
ptr->wsabuf.buf = ptr->buf;
|
||||||
|
ptr->wsabuf.len = packetLength + 6;
|
||||||
|
ptr->IOCPInstance = data->IOCPInstance;
|
||||||
|
|
||||||
|
continuePacket.convToN();
|
||||||
|
memcpy(ptr->wsabuf.buf, continuePacket.serialized, packetLength + 6);
|
||||||
|
data->sendbytes = packetLength + 6;
|
||||||
|
data->IOCPInstance->send(ptr, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::registerUser(std::string userName) {
|
||||||
|
Chattr::LoginRequestPacket loginRequestPacket;
|
||||||
|
loginRequestPacket.__data.packetType = Chattr::PacketCategory::PACKET_REQUEST;
|
||||||
|
loginRequestPacket.__data.requestType = Chattr::RequestType::LOGIN;
|
||||||
|
loginRequestPacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
loginRequestPacket.__data.packetLength = userName.size();
|
||||||
|
memcpy(loginRequestPacket.__data.data, userName.c_str(), userName.size());
|
||||||
|
|
||||||
|
int packetLength = loginRequestPacket.__data.packetLength;
|
||||||
|
|
||||||
|
data_->recvbytes = data_->sendbytes = 0;
|
||||||
|
data_->wsabuf.len = packetLength + 8;
|
||||||
|
|
||||||
|
loginRequestPacket.convToN();
|
||||||
|
memcpy(data_->wsabuf.buf, loginRequestPacket.serialized, packetLength + 8);
|
||||||
|
data_->sendbytes = packetLength + 8;
|
||||||
|
iocp_.send(data_, 1, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::deleteUser(Snowflake UID) {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
userNames_.erase(UID);
|
||||||
|
std::shared_ptr<TCPSocket> sock = UID2userSocket_[UID];
|
||||||
|
UID2userSocket_.erase(UID);
|
||||||
|
userSocket2UID_.erase(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<Snowflake, std::string>> ClientManager::getUserList() {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
std::vector<std::pair<Snowflake, std::string>> userList;
|
||||||
|
userList.reserve(userNames_.size());
|
||||||
|
|
||||||
|
for (auto user : userNames_)
|
||||||
|
userList.push_back(user);
|
||||||
|
|
||||||
|
return userList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Snowflake ClientManager::createRoom(std::string roomName) {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
Snowflake RID = GenerateID();
|
||||||
|
roomNames_[RID] = roomName;
|
||||||
|
rooms_[RID] = std::unordered_map<Snowflake, std::shared_ptr<TCPSocket>>();
|
||||||
|
return RID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::deleteRoom(Snowflake RID) {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
roomNames_.erase(RID);
|
||||||
|
rooms_.erase(RID);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<Snowflake, std::string>> ClientManager::getRoomList() {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
std::vector<std::pair<Snowflake, std::string>> roomList;
|
||||||
|
roomList.reserve(roomNames_.size());
|
||||||
|
|
||||||
|
for (auto user : roomNames_)
|
||||||
|
roomList.push_back(user);
|
||||||
|
|
||||||
|
return roomList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::joinRoom(Snowflake UID, Snowflake RID) {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
std::shared_ptr<TCPSocket> sock = UID2userSocket_[UID];
|
||||||
|
rooms_[RID][UID] = sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::exitRoom(Snowflake UID, Snowflake RID) {
|
||||||
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
|
rooms_[RID].erase(UID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientManager::run() {
|
||||||
|
StringTokenizer tokenizer;
|
||||||
|
std::string nickname;
|
||||||
|
|
||||||
|
std::cout << "Please enter your nickname: ";
|
||||||
|
std::getline(std::cin, nickname);
|
||||||
|
tokenizer.set(nickname.c_str(), nickname.size());
|
||||||
|
|
||||||
|
registerUser(tokenizer.get()[0]);
|
||||||
|
|
||||||
|
std::cout << "Commads:" << std::endl;
|
||||||
|
std::cout << "/w <username> : Send direct message to specified user" << std::endl;
|
||||||
|
std::cout << "/join <roomname> : Enter specified room" << std::endl;
|
||||||
|
std::cout << "/exit : Exit current room" << std::endl;
|
||||||
|
std::cout << "/create <roomname> : Create room" << std::endl;
|
||||||
|
std::cout << "/list : Print all registred users" << std::endl;
|
||||||
|
std::cout << "/exit : Terminate this program (When you are not in room)" << std::endl;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
std::string input;
|
||||||
|
|
||||||
|
if (inRoom_) {
|
||||||
|
std::cout << "[" << nickname << "@" << roomNames_[myRoomID_] << "]" << " ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "[" << nickname << "]" << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::getline(std::cin, input);
|
||||||
|
tokenizer.set(input.c_str(), input.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
Client/src/Socket/Log.cpp
Normal file
25
Client/src/Socket/Log.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "Socket/Log.hpp"
|
||||||
|
|
||||||
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "spdlog/sinks/msvc_sink.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "precomp.hpp"
|
||||||
|
|
||||||
|
namespace Chattr::log {
|
||||||
|
|
||||||
|
void setDefaultLogger(spdlog::level::level_enum logLevel, gsl::czstring logFileName, std::uint32_t logFileSize, std::uint32_t logFileCount) {
|
||||||
|
std::vector<spdlog::sink_ptr> sinks;
|
||||||
|
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
|
||||||
|
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logFileName, logFileSize, logFileCount, false));
|
||||||
|
#ifdef _WIN32
|
||||||
|
sinks.push_back(std::make_shared<spdlog::sinks::msvc_sink_mt>());
|
||||||
|
#endif
|
||||||
|
auto chatteringLogger = std::make_shared<spdlog::logger>("Chattering Logger", begin(sinks), end(sinks));
|
||||||
|
chatteringLogger->set_level(logLevel);
|
||||||
|
spdlog::set_default_logger(chatteringLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
56
Client/src/Utils/ConfigManager.cpp
Normal file
56
Client/src/Utils/ConfigManager.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "Utils/ConfigManager.hpp"
|
||||||
|
#include "precomp.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Chattr {
|
||||||
|
ConfigManager::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"] = 6;
|
||||||
|
config.configJsonRoot["IP"] = "::1";
|
||||||
|
config.configJsonRoot["Port"] = 9010;
|
||||||
|
config.configJsonRoot["LogLevel"] = 1;
|
||||||
|
config.configJsonRoot["LogfileName"] = "Chattering.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 != 4 && config.ipVersion != 6)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
|
#define _CLIENT
|
||||||
#include "Socket/TCPSocket.hpp"
|
#include "Socket/TCPSocket.hpp"
|
||||||
#include "Socket/Address.hpp"
|
#include "Socket/Address.hpp"
|
||||||
#include "Socket/Log.hpp"
|
#include "Socket/Log.hpp"
|
||||||
#include "Packet/Packet.hpp"
|
#include "Packet/Packet.hpp"
|
||||||
#include "Utils/Snowflake.hpp"
|
#include "Utils/Snowflake.hpp"
|
||||||
|
#include "ClientManager/ClientManager.hpp"
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Chattr::ClientManager client;
|
||||||
|
client.init();
|
||||||
|
client.run();
|
||||||
|
|
||||||
Chattr::TCPSocket sock;
|
Chattr::TCPSocket sock;
|
||||||
sock.init(AF_INET6);
|
sock.init(AF_INET6);
|
||||||
|
|
||||||
|
|||||||
@@ -16,27 +16,29 @@ public:
|
|||||||
void init(_Callable _IOCPClient) {
|
void init(_Callable _IOCPClient) {
|
||||||
auto config = ConfigManager::load();
|
auto config = ConfigManager::load();
|
||||||
log::setDefaultLogger(config.logLevel, config.logFileName, config.logfileSize, config.logfileCount);
|
log::setDefaultLogger(config.logLevel, config.logFileName, config.logfileSize, config.logfileCount);
|
||||||
threadPool_.init(2);
|
threadPool_.init(0);
|
||||||
iocp_.init(&threadPool_, _IOCPClient);
|
iocp_.init(&threadPool_, _IOCPClient);
|
||||||
|
|
||||||
struct Address serveraddr;
|
struct Address serveraddr;
|
||||||
if (config.ipVersion == 4) {
|
if (config.ipVersion == 4) {
|
||||||
listenSock_.init(AF_INET);
|
listenSock_.init(AF_INET);
|
||||||
serveraddr.set(AF_INET, INADDR_ANY, config.listenPort);
|
serveraddr.set(AF_INET, config.IP, config.Port);
|
||||||
clientAddr_.setType(AF_INET);
|
clientAddr_.setType(AF_INET);
|
||||||
}
|
}
|
||||||
else if (config.ipVersion == 6) {
|
else if (config.ipVersion == 6) {
|
||||||
listenSock_.init(AF_INET6);
|
listenSock_.init(AF_INET6);
|
||||||
serveraddr.set(AF_INET6, in6addr_any, config.listenPort);
|
serveraddr.set(AF_INET6, config.IP, config.Port);
|
||||||
clientAddr_.setType(AF_INET6);
|
clientAddr_.setType(AF_INET6);
|
||||||
}
|
}
|
||||||
listenSock_.bind(serveraddr);
|
listenSock_.bind(serveraddr);
|
||||||
listenSock_.listen(SOMAXCONN);
|
listenSock_.listen(SOMAXCONN);
|
||||||
|
|
||||||
|
spdlog::info("Server listening on [{}]", (std::string)serveraddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
init([this](ThreadPool* thread, IOCPPASSINDATA* data) {
|
init([this](ThreadPool* thread, IOCPPASSINDATA* data) {
|
||||||
_IOCPClient(thread, data);
|
this->_IOCPClient(thread, data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +55,7 @@ public:
|
|||||||
void deleteUser(Snowflake UID);
|
void deleteUser(Snowflake UID);
|
||||||
std::vector<std::pair<Snowflake, std::string>> getUserList();
|
std::vector<std::pair<Snowflake, std::string>> getUserList();
|
||||||
|
|
||||||
void createRoom(std::string roomName);
|
Snowflake createRoom(std::string roomName);
|
||||||
void deleteRoom(Snowflake RID);
|
void deleteRoom(Snowflake RID);
|
||||||
std::vector<std::pair<Snowflake, std::string>> getRoomList();
|
std::vector<std::pair<Snowflake, std::string>> getRoomList();
|
||||||
|
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ void ServerManager::processLoginRequestPacket(LoginRequestPacket loginRequestPac
|
|||||||
LoginResponsePacket loginResponsePacket;
|
LoginResponsePacket loginResponsePacket;
|
||||||
loginResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
loginResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN;
|
loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN;
|
||||||
loginResponsePacket.__data.dataType = Chattr::DataType::TEXT;
|
loginResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake);
|
loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake);
|
||||||
loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
Snowflake yourId = userSocket2UID_[data->socket];
|
Snowflake yourId = userSocket2UID_[data->socket];
|
||||||
@@ -189,15 +189,101 @@ void ServerManager::processLoginRequestPacket(LoginRequestPacket loginRequestPac
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::processRoomCreateRequestPacket(RoomCreateRequestPacket roomCreateRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
void ServerManager::processRoomCreateRequestPacket(RoomCreateRequestPacket roomCreateRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
std::string roomName(
|
||||||
|
(char*)roomCreateRequestPacket.__data.data,
|
||||||
|
roomCreateRequestPacket.__data.packetLength);
|
||||||
|
Snowflake RID = createRoom(roomName);
|
||||||
|
|
||||||
|
RoomCreateResponsePacket roomCreateResponsePacket;
|
||||||
|
roomCreateResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
roomCreateResponsePacket.__data.requestType = Chattr::RequestType::ROOM_CREATE;
|
||||||
|
roomCreateResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
roomCreateResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake);
|
||||||
|
roomCreateResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
::memcpy(roomCreateResponsePacket.__data.createdRoomId, &RID, sizeof(Snowflake));
|
||||||
|
|
||||||
|
roomCreateResponsePacket.convToN();
|
||||||
|
memcpy(data->wsabuf.buf, roomCreateResponsePacket.serialized, 18);
|
||||||
|
data->sendbytes = 18;
|
||||||
|
data->wsabuf.len = 18;
|
||||||
|
data->IOCPInstance->send(data, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::processRoomListRequest(RoomListRequestPacket roomListRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
void ServerManager::processRoomListRequest(RoomListRequestPacket roomListRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
auto roomsList = getRoomList();
|
||||||
|
|
||||||
|
for (auto room : roomsList) {
|
||||||
|
RoomListResponsePacket roomListResponsePacket;
|
||||||
|
roomListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
roomListResponsePacket.__data.requestType = Chattr::RequestType::ROOM_LIST;
|
||||||
|
roomListResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
roomListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + room.second.size();
|
||||||
|
roomListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
roomListResponsePacket.__data.roomCount = roomsList.size();
|
||||||
|
::memcpy(roomListResponsePacket.__data.roomId, &room.first, sizeof(Snowflake));
|
||||||
|
::memcpy(roomListResponsePacket.__data.name, room.second.c_str(), room.second.size());
|
||||||
|
|
||||||
|
int packetLength = roomListResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA;
|
||||||
|
::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
ptr->socket = data->socket;
|
||||||
|
ptr->recvbytes = ptr->sendbytes = 0;
|
||||||
|
ptr->wsabuf.buf = ptr->buf;
|
||||||
|
ptr->wsabuf.len = packetLength + 8;
|
||||||
|
ptr->IOCPInstance = data->IOCPInstance;
|
||||||
|
|
||||||
|
roomListResponsePacket.convToN();
|
||||||
|
memcpy(ptr->wsabuf.buf, roomListResponsePacket.serialized, packetLength + 8);
|
||||||
|
data->sendbytes = packetLength + 8;
|
||||||
|
data->IOCPInstance->send(ptr, 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::processRoomJoinRequestPacket(RoomJoinRequestPacket roomJoinRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
void ServerManager::processRoomJoinRequestPacket(RoomJoinRequestPacket roomJoinRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
Snowflake myID, roomID;
|
||||||
|
::memcpy(&myID.snowflake, roomJoinRequestPacket.__data.myId, sizeof(Snowflake));
|
||||||
|
::memcpy(&roomID.snowflake, roomJoinRequestPacket.__data.roomId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
joinRoom(myID, roomID);
|
||||||
|
|
||||||
|
RoomJoinResponsePacket roomJoinResponsePacket;
|
||||||
|
roomJoinResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
roomJoinResponsePacket.__data.requestType = Chattr::RequestType::ROOM_JOIN;
|
||||||
|
roomJoinResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
roomJoinResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
roomJoinResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
int packetLength = roomJoinResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
roomJoinResponsePacket.convToN();
|
||||||
|
::memcpy(data->wsabuf.buf, roomJoinResponsePacket.serialized, 10);
|
||||||
|
data->sendbytes = 10;
|
||||||
|
data->wsabuf.len = 10;
|
||||||
|
data->IOCPInstance->send(data, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::processRoomExitRequestPacket(RoomExitRequestPacket roomExitRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
void ServerManager::processRoomExitRequestPacket(RoomExitRequestPacket roomExitRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
|
Snowflake myID, roomID;
|
||||||
|
::memcpy(&myID.snowflake, roomExitRequestPacket.__data.myId, sizeof(Snowflake));
|
||||||
|
::memcpy(&roomID.snowflake, roomExitRequestPacket.__data.roomId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
exitRoom(myID, roomID);
|
||||||
|
|
||||||
|
RoomExitResponsePacket roomExitResponsePacket;
|
||||||
|
roomExitResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
roomExitResponsePacket.__data.requestType = Chattr::RequestType::ROOM_EXIT;
|
||||||
|
roomExitResponsePacket.__data.dataType = Chattr::DataType::BINARY;
|
||||||
|
roomExitResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
roomExitResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
int packetLength = roomExitResponsePacket.__data.packetLength;
|
||||||
|
|
||||||
|
roomExitResponsePacket.convToN();
|
||||||
|
::memcpy(data->wsabuf.buf, roomExitResponsePacket.serialized, 10);
|
||||||
|
data->sendbytes = 10;
|
||||||
|
data->wsabuf.len = 10;
|
||||||
|
data->IOCPInstance->send(data, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::processUsersListRequestPacket(UsersListRequestPacket usersListRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
void ServerManager::processUsersListRequestPacket(UsersListRequestPacket usersListRequestPacket, Chattr::IOCPPASSINDATA* data) {
|
||||||
@@ -281,6 +367,51 @@ void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPAS
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data) {
|
void ServerManager::processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data) {
|
||||||
|
Snowflake destID;
|
||||||
|
::memcpy(&destID.snowflake, continuePacket.__data.destId, sizeof(Snowflake));
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<TCPSocket>> destinationSockets;
|
||||||
|
|
||||||
|
if (userNames_.find(destID) != userNames_.end())
|
||||||
|
destinationSockets.push_back(UID2userSocket_[destID]);
|
||||||
|
else
|
||||||
|
for (auto user : rooms_[destID])
|
||||||
|
destinationSockets.push_back(user.second);
|
||||||
|
|
||||||
|
spdlog::info("Received [{}] from : [{}] to : [{}]",
|
||||||
|
std::string((char*)continuePacket.__data.data, continuePacket.__data.packetLength - (sizeof(std::uint16_t) * 5)),
|
||||||
|
(std::string)data->socket->remoteAddr,
|
||||||
|
destID.snowflake);
|
||||||
|
|
||||||
|
ResponsePacket responsePacket;
|
||||||
|
responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE;
|
||||||
|
responsePacket.__data.requestType = Chattr::RequestType::DATA;
|
||||||
|
responsePacket.__data.dataType = Chattr::DataType::TEXT;
|
||||||
|
responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode);
|
||||||
|
responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK;
|
||||||
|
|
||||||
|
responsePacket.convToN();
|
||||||
|
memcpy(data->wsabuf.buf, responsePacket.serialized, 10);
|
||||||
|
data->sendbytes = 10;
|
||||||
|
data->wsabuf.len = 10;
|
||||||
|
data->IOCPInstance->send(data, 1, 0);
|
||||||
|
|
||||||
|
int packetLength = continuePacket.__data.packetLength;
|
||||||
|
|
||||||
|
for (auto dest : destinationSockets) {
|
||||||
|
Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA;
|
||||||
|
::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
ptr->socket = dest;
|
||||||
|
ptr->recvbytes = ptr->sendbytes = 0;
|
||||||
|
ptr->wsabuf.buf = ptr->buf;
|
||||||
|
ptr->wsabuf.len = packetLength + 6;
|
||||||
|
ptr->IOCPInstance = data->IOCPInstance;
|
||||||
|
|
||||||
|
continuePacket.convToN();
|
||||||
|
memcpy(ptr->wsabuf.buf, continuePacket.serialized, packetLength + 6);
|
||||||
|
data->sendbytes = packetLength + 6;
|
||||||
|
data->IOCPInstance->send(ptr, 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::registerUser(std::string userName, std::shared_ptr<TCPSocket> sock) {
|
void ServerManager::registerUser(std::string userName, std::shared_ptr<TCPSocket> sock) {
|
||||||
@@ -310,11 +441,12 @@ std::vector<std::pair<Snowflake, std::string>> ServerManager::getUserList() {
|
|||||||
return userList;
|
return userList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::createRoom(std::string roomName) {
|
Snowflake ServerManager::createRoom(std::string roomName) {
|
||||||
std::lock_guard<std::mutex> lock(resourceMutex_);
|
std::lock_guard<std::mutex> lock(resourceMutex_);
|
||||||
Snowflake RID = GenerateID();
|
Snowflake RID = GenerateID();
|
||||||
roomNames_[RID] = roomName;
|
roomNames_[RID] = roomName;
|
||||||
rooms_[RID] = std::unordered_map<Snowflake, std::shared_ptr<TCPSocket>>();
|
rooms_[RID] = std::unordered_map<Snowflake, std::shared_ptr<TCPSocket>>();
|
||||||
|
return RID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerManager::deleteRoom(Snowflake RID) {
|
void ServerManager::deleteRoom(Snowflake RID) {
|
||||||
|
|||||||
25
Server/src/Socket/Log.cpp
Normal file
25
Server/src/Socket/Log.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "Socket/Log.hpp"
|
||||||
|
|
||||||
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "spdlog/sinks/msvc_sink.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "precomp.hpp"
|
||||||
|
|
||||||
|
namespace Chattr::log {
|
||||||
|
|
||||||
|
void setDefaultLogger(spdlog::level::level_enum logLevel, gsl::czstring logFileName, std::uint32_t logFileSize, std::uint32_t logFileCount) {
|
||||||
|
std::vector<spdlog::sink_ptr> sinks;
|
||||||
|
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
|
||||||
|
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logFileName, logFileSize, logFileCount, false));
|
||||||
|
#ifdef _WIN32
|
||||||
|
sinks.push_back(std::make_shared<spdlog::sinks::msvc_sink_mt>());
|
||||||
|
#endif
|
||||||
|
auto chatteringLogger = std::make_shared<spdlog::logger>("Chattering Logger", begin(sinks), end(sinks));
|
||||||
|
chatteringLogger->set_level(logLevel);
|
||||||
|
spdlog::set_default_logger(chatteringLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@ ConfigManager::Config ConfigManager::load() {
|
|||||||
if (!configfile.is_open()) {
|
if (!configfile.is_open()) {
|
||||||
std::ofstream defaultConfig("config.json", std::ios::out);
|
std::ofstream defaultConfig("config.json", std::ios::out);
|
||||||
config.configJsonRoot["IP Version"] = 6;
|
config.configJsonRoot["IP Version"] = 6;
|
||||||
config.configJsonRoot["Listen Port"] = 9010;
|
config.configJsonRoot["IP"] = "::";
|
||||||
|
config.configJsonRoot["Port"] = 9010;
|
||||||
config.configJsonRoot["LogLevel"] = 1;
|
config.configJsonRoot["LogLevel"] = 1;
|
||||||
config.configJsonRoot["LogfileName"] = "Chattering.log";
|
config.configJsonRoot["LogfileName"] = "Chattering.log";
|
||||||
config.configJsonRoot["LogfileSize"] = UINT32_MAX;
|
config.configJsonRoot["LogfileSize"] = UINT32_MAX;
|
||||||
@@ -30,8 +31,10 @@ ConfigManager::Config ConfigManager::load() {
|
|||||||
if (config.ipVersion != 4 && config.ipVersion != 6)
|
if (config.ipVersion != 4 && config.ipVersion != 6)
|
||||||
throw std::runtime_error("Invalid IP Version.");
|
throw std::runtime_error("Invalid IP Version.");
|
||||||
|
|
||||||
config.listenPort = config.configJsonRoot["Listen Port"].asInt();
|
config.IP = config.configJsonRoot["IP"].asCString();
|
||||||
if (config.listenPort < 0 || config.listenPort > 65535)
|
|
||||||
|
config.Port = config.configJsonRoot["Port"].asInt();
|
||||||
|
if (config.Port < 0 || config.Port > 65535)
|
||||||
throw std::runtime_error("Invalid listen port.");
|
throw std::runtime_error("Invalid listen port.");
|
||||||
|
|
||||||
int ll_ = config.configJsonRoot["LogLevel"].asInt();
|
int ll_ = config.configJsonRoot["LogLevel"].asInt();
|
||||||
|
|||||||
@@ -19,18 +19,18 @@ void IOCP::destruct() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOCP::registerSocket(Chattr::IOCPPASSINDATA* data) {
|
void IOCP::registerSocket(IOCPPASSINDATA* data) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE returnData = ::CreateIoCompletionPort((HANDLE)data->socket->sock, completionPort_, data->socket->sock, 0);
|
HANDLE returnData = ::CreateIoCompletionPort((HANDLE)data->socket->sock, completionPort_, data->socket->sock, 0);
|
||||||
if (returnData == 0)
|
if (returnData == 0)
|
||||||
completionPort_ = returnData;
|
completionPort_ = returnData;
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
int flags = ::fcntl(data->socket->sock, F_GETFL);
|
// int flags = ::fcntl(data->socket->sock, F_GETFL);
|
||||||
flags |= O_NONBLOCK;
|
// flags |= O_NONBLOCK;
|
||||||
fcntl(data->socket->sock, F_SETFL, flags);
|
// fcntl(data->socket->sock, F_SETFL, flags);
|
||||||
|
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
ev.events = EPOLLIN | EPOLLONESHOT;
|
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
|
||||||
ev.data.ptr = data;
|
ev.data.ptr = data;
|
||||||
int rc = epoll_ctl(epollfd_, EPOLL_CTL_ADD, data->socket->sock, &ev);
|
int rc = epoll_ctl(epollfd_, EPOLL_CTL_ADD, data->socket->sock, &ev);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
@@ -45,20 +45,23 @@ int IOCP::recv(Chattr::IOCPPASSINDATA* data, int bufferCount) {
|
|||||||
return ::WSARecv(data->socket->sock, &data->wsabuf, bufferCount, &recvbytes, &flags, &data->overlapped, NULL);
|
return ::WSARecv(data->socket->sock, &data->wsabuf, bufferCount, &recvbytes, &flags, &data->overlapped, NULL);
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
ev.events = EPOLLIN | EPOLLONESHOT;
|
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
|
||||||
ev.data.ptr = data;
|
ev.data.ptr = data;
|
||||||
return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev);
|
return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int IOCP::send(Chattr::IOCPPASSINDATA* data, int bufferCount, int __flags) {
|
int IOCP::send(Chattr::IOCPPASSINDATA* data, int bufferCount, int __flags, bool client) {
|
||||||
data->event = IOCPEVENT::WRITE;
|
data->event = IOCPEVENT::WRITE;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD sendbytes = 0;
|
DWORD sendbytes = 0;
|
||||||
return ::WSASend(data->socket->sock, &data->wsabuf, bufferCount, &sendbytes, __flags, &data->overlapped, NULL);
|
return ::WSASend(data->socket->sock, &data->wsabuf, bufferCount, &sendbytes, __flags, &data->overlapped, NULL);
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
ev.events = EPOLLOUT | EPOLLONESHOT;
|
if (client)
|
||||||
|
ev.events = EPOLLIN | EPOLLOUT | EPOLLET | EPOLLONESHOT;
|
||||||
|
else
|
||||||
|
ev.events = EPOLLOUT | EPOLLET | EPOLLONESHOT;
|
||||||
ev.data.ptr = data;
|
ev.data.ptr = data;
|
||||||
return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev);
|
return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,18 +10,6 @@
|
|||||||
|
|
||||||
namespace Chattr::log {
|
namespace Chattr::log {
|
||||||
|
|
||||||
void setDefaultLogger(spdlog::level::level_enum logLevel, gsl::czstring logFileName, std::uint32_t logFileSize, std::uint32_t logFileCount) {
|
|
||||||
std::vector<spdlog::sink_ptr> sinks;
|
|
||||||
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
|
|
||||||
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logFileName, logFileSize, logFileCount, false));
|
|
||||||
#ifdef _WIN32
|
|
||||||
sinks.push_back(std::make_shared<spdlog::sinks::msvc_sink_mt>());
|
|
||||||
#endif
|
|
||||||
auto chatteringLogger = std::make_shared<spdlog::logger>("Chattering Logger", begin(sinks), end(sinks));
|
|
||||||
chatteringLogger->set_level(logLevel);
|
|
||||||
spdlog::set_default_logger(chatteringLogger);
|
|
||||||
}
|
|
||||||
|
|
||||||
void critical(gsl::czstring msg) {
|
void critical(gsl::czstring msg) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
LPSTR msgbuf = nullptr;
|
LPSTR msgbuf = nullptr;
|
||||||
|
|||||||
@@ -84,26 +84,61 @@ public:
|
|||||||
RequestType requestType;
|
RequestType requestType;
|
||||||
DataType dataType;
|
DataType dataType;
|
||||||
std::uint16_t packetLength;
|
std::uint16_t packetLength;
|
||||||
std::uint16_t destId[4];
|
std::uint16_t myId[4];
|
||||||
|
std::uint16_t roomId[4];
|
||||||
std::uint8_t name[];
|
std::uint8_t name[];
|
||||||
} __data;
|
} __data;
|
||||||
std::uint8_t serialized[1500] = "";
|
std::uint8_t serialized[1500] = "";
|
||||||
};
|
};
|
||||||
std::uint8_t* convToN() {
|
std::uint8_t* convToN() {
|
||||||
__data.packetLength = ::htons(__data.packetLength);
|
__data.packetLength = ::htons(__data.packetLength);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++) {
|
||||||
__data.destId[i] = ::htons(__data.destId[i]);
|
__data.myId[i] = ::htons(__data.myId[i]);
|
||||||
|
__data.roomId[i] = ::htons(__data.roomId[i]);
|
||||||
|
}
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
std::uint8_t* convToH() {
|
std::uint8_t* convToH() {
|
||||||
__data.packetLength = ::ntohs(__data.packetLength);
|
__data.packetLength = ::ntohs(__data.packetLength);
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++) {
|
||||||
__data.destId[i] = ::ntohs(__data.destId[i]);
|
__data.myId[i] = ::ntohs(__data.myId[i]);
|
||||||
|
__data.roomId[i] = ::ntohs(__data.roomId[i]);
|
||||||
|
}
|
||||||
return serialized;
|
return serialized;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class alignas(4) RoomExitRequestPacket : public Packet {};
|
class alignas(4) RoomExitRequestPacket : public Packet {
|
||||||
|
public:
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
PacketCategory packetType;
|
||||||
|
RequestType requestType;
|
||||||
|
DataType dataType;
|
||||||
|
std::uint16_t packetLength;
|
||||||
|
std::uint16_t myId[4];
|
||||||
|
std::uint16_t roomId[4];
|
||||||
|
std::uint8_t name[];
|
||||||
|
} __data;
|
||||||
|
std::uint8_t serialized[1500] = "";
|
||||||
|
};
|
||||||
|
std::uint8_t* convToN() {
|
||||||
|
__data.packetLength = ::htons(__data.packetLength);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
__data.myId[i] = ::htons(__data.myId[i]);
|
||||||
|
__data.roomId[i] = ::htons(__data.roomId[i]);
|
||||||
|
}
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
std::uint8_t* convToH() {
|
||||||
|
__data.packetLength = ::ntohs(__data.packetLength);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
__data.myId[i] = ::ntohs(__data.myId[i]);
|
||||||
|
__data.roomId[i] = ::ntohs(__data.roomId[i]);
|
||||||
|
}
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class alignas(4) UsersListRequestPacket : public Packet {};
|
class alignas(4) UsersListRequestPacket : public Packet {};
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public:
|
|||||||
void registerSocket(IOCPPASSINDATA* data);
|
void registerSocket(IOCPPASSINDATA* data);
|
||||||
|
|
||||||
int recv(IOCPPASSINDATA* data, int bufferCount);
|
int recv(IOCPPASSINDATA* data, int bufferCount);
|
||||||
int send(IOCPPASSINDATA* data, int bufferCount, int __flags);
|
int send(IOCPPASSINDATA* data, int bufferCount, int __flags, bool client = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct WSAManager wsaManager;
|
struct WSAManager wsaManager;
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ public:
|
|||||||
struct Config {
|
struct Config {
|
||||||
Json::Value configJsonRoot;
|
Json::Value configJsonRoot;
|
||||||
std::uint32_t ipVersion = 0;
|
std::uint32_t ipVersion = 0;
|
||||||
std::uint32_t listenPort = 0;
|
gsl::czstring IP = "";
|
||||||
|
std::uint32_t Port = 0;
|
||||||
spdlog::level::level_enum logLevel = spdlog::level::off;
|
spdlog::level::level_enum logLevel = spdlog::level::off;
|
||||||
gsl::czstring logFileName = "";
|
gsl::czstring logFileName = "";
|
||||||
std::uint32_t logfileSize = 0;
|
std::uint32_t logfileSize = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user