diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index d40a264..7b50b93 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -56,6 +56,7 @@ enum class SerialPacketType { //disconnect from the server DISCONNECT_REQUEST, + DISCONNECT_RESPONSE, DISCONNECT_FORCED, //load the account diff --git a/common/network/serial_utility.cpp b/common/network/serial_utility.cpp index ddad0e7..086e6a7 100644 --- a/common/network/serial_utility.cpp +++ b/common/network/serial_utility.cpp @@ -55,6 +55,7 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_RESPONSE: case SerialPacketType::DISCONNECT_REQUEST: + case SerialPacketType::DISCONNECT_RESPONSE: case SerialPacketType::DISCONNECT_FORCED: case SerialPacketType::LOGIN_REQUEST: case SerialPacketType::LOGIN_RESPONSE: @@ -104,6 +105,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::JOIN_REQUEST: case SerialPacketType::JOIN_RESPONSE: case SerialPacketType::DISCONNECT_REQUEST: + case SerialPacketType::DISCONNECT_RESPONSE: case SerialPacketType::DISCONNECT_FORCED: case SerialPacketType::LOGIN_REQUEST: case SerialPacketType::LOGIN_RESPONSE: diff --git a/server/server_application.hpp b/server/server_application.hpp index a91bbbc..77cb847 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -70,29 +70,43 @@ private: //handle incoming traffic void HandlePacket(SerialPacket* const); + //heartbeat sustem + void HandlePing(ServerPacket* const); + void HandlePong(ServerPacket* const); + //basic connections void HandleBroadcastRequest(ServerPacket* const); void HandleJoinRequest(ClientPacket* const); - void HandleDisconnect(ClientPacket* const); - void HandleShutdown(ClientPacket* const); + void HandleLoginRequest(ClientPacket* const); + + //client disconnections + void HandleLogoutRequest(ClientPacket* const); + void HandleDisconnectRequest(ClientPacket* const); + + //server commands +// void HandleDisconnectForced(ClientPacket* const); + void HandleShutdownRequest(ClientPacket* const); //map management - void HandleRegionRequest(RegionPacket* const); +// void HandleRegionRequest(RegionPacket* const); //character management - void HandleCharacterNew(CharacterPacket* const); - void HandleCharacterDelete(CharacterPacket* const); - void HandleCharacterUpdate(CharacterPacket* const); +// void HandleCharacterNew(CharacterPacket* const); +// void HandleCharacterDelete(CharacterPacket* const); +// void HandleCharacterUpdate(CharacterPacket* const); //mismanagement - void HandleSynchronize(ClientPacket* const); +// void HandleSynchronize(ClientPacket* const); //utility methods //TODO: a function that only sends to characters in a certain proximity - void CleanupLostConnection(int index); - void PumpPacket(SerialPacket* const); - void PumpCharacterUnload(int uid); - void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); +// void CleanupLostConnection(int index); +// void PumpPacket(SerialPacket* const); +// void PumpCharacterUnload(int uid); +// void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); + + //data management + void SaveServerState(); //APIs and utilities sqlite3* database = nullptr; diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 0c80ff8..df12171 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -180,7 +180,7 @@ void ServerApplication::Proc() { //find and unload the characters associated with this account characterMgr.UnloadIf([&](std::pair character) -> bool { if (character.second.GetOwner() == account.first) { - PumpCharacterUnload(character.first); +// PumpCharacterUnload(character.first); return true; } return false; @@ -227,43 +227,40 @@ void ServerApplication::Quit() { void ServerApplication::HandlePacket(SerialPacket* const argPacket) { switch(argPacket->type) { //heartbeat system - case SerialPacketType::PING: { - ServerPacket newPacket; - newPacket.type = SerialPacketType::PONG; - network.SendTo(argPacket->srcAddress, &newPacket); - } + case SerialPacketType::PING: + HandlePing(static_cast(argPacket)); break; case SerialPacketType::PONG: - clientMgr.HandlePong(static_cast(argPacket)); + HandlePong(static_cast(argPacket)); break; //client connections case SerialPacketType::BROADCAST_REQUEST: -// HandleBroadcastRequest(static_cast(argPacket)); + HandleBroadcastRequest(static_cast(argPacket)); break; case SerialPacketType::JOIN_REQUEST: -// HandleJoinRequest(static_cast(argPacket)); + HandleJoinRequest(static_cast(argPacket)); break; case SerialPacketType::LOGIN_REQUEST: -// HandleLoginRequest(static_cast(argPacket)); + HandleLoginRequest(static_cast(argPacket)); break; //client disconnections - case SerialPacketType::DISCONNECT_REQUEST: -// HandleDisconnectRequest(static_cast(argPacket)); - break; - case SerialPacketType::DISCONNECT_FORCED: -// HandleDisconnectForced(static_cast(argPacket)); - break; case SerialPacketType::LOGOUT_REQUEST: -// HandleLogoutRequest(static_cast(argPacket)); + HandleLogoutRequest(static_cast(argPacket)); + break; + case SerialPacketType::DISCONNECT_REQUEST: + HandleDisconnectRequest(static_cast(argPacket)); break; //server commands - case SerialPacketType::SHUTDOWN_REQUEST: -// HandleShutdownRequest(static_cast(argPacket)); + case SerialPacketType::DISCONNECT_FORCED: +// HandleDisconnectForced(static_cast(argPacket)); break; - + case SerialPacketType::SHUTDOWN_REQUEST: + HandleShutdownRequest(static_cast(argPacket)); + break; +/* //data management & queries case SerialPacketType::REGION_REQUEST: // HandleRegionRequest(static_cast(argPacket)); @@ -310,7 +307,7 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { //TODO: enemy management //TODO: text - +*/ //handle errors default: { std::ostringstream msg; diff --git a/server/server_methods.cpp b/server/server_methods.cpp index 7e84f8e..202e075 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -25,11 +25,36 @@ #include #include +//------------------------- +//these should've come standard +//------------------------- + +bool operator==(IPaddress lhs, IPaddress rhs) { + return lhs.host == rhs.host && lhs.port == rhs.port; +} + +bool operator!=(IPaddress lhs, IPaddress rhs) { + return !(lhs == rhs); +} + +//------------------------- +//heartbeat system +//------------------------- + +void ServerApplication::HandlePing(ServerPacket* const argPacket) { + ServerPacket newPacket; + newPacket.type = SerialPacketType::PONG; + network.SendTo(argPacket->srcAddress, &newPacket); +} + +void ServerApplication::HandlePong(ServerPacket* const argPacket) { + clientMgr.HandlePong(argPacket); +} + //------------------------- //basic connections //------------------------- -//SET: utility void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { //send the server's data ServerPacket newPacket; @@ -42,14 +67,33 @@ void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } -//SET: connections void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { //register the client int clientIndex = clientMgr.Create(argPacket->srcAddress); + //send the client their info + ClientPacket newPacket; + newPacket.type = SerialPacketType::JOIN_RESPONSE; + newPacket.clientIndex = clientIndex; + + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + //finished this routine + std::cout << "New join, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; +} + +void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) { + //get the client data + ClientData* clientData = clientMgr.Get(argPacket->clientIndex); + + if (clientData == nullptr || clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified client index detected: " << argPacket->clientIndex << std::endl; + //TODO: rejection message? + return; + } + //load the user account - //TODO: handle passwords - int accountIndex = accountMgr.Load(argPacket->username, clientIndex); + int accountIndex = accountMgr.Load(argPacket->username, argPacket->clientIndex); //Cannot load if (accountIndex < 0) { @@ -57,85 +101,132 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { msg << "Account already loaded: " << argPacket->username; TextPacket newPacket; - newPacket.type = SerialPacketType::JOIN_REJECTION; - memset(newPacket.name, 0, PACKET_STRING_SIZE); + newPacket.type = SerialPacketType::LOGIN_REJECTION; +// memset(newPacket.name, 0, PACKET_STRING_SIZE); strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); - clientMgr.Unload(clientIndex); + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); return; } //send the client their info ClientPacket newPacket; - newPacket.type = SerialPacketType::JOIN_RESPONSE; - newPacket.clientIndex = clientIndex; + newPacket.type = SerialPacketType::LOGIN_RESPONSE; + newPacket.clientIndex = argPacket->clientIndex; newPacket.accountIndex = accountIndex; - network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); //finished this routine - std::cout << "New connection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; + std::cout << "New login, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } -//SET: connections -void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { - //TODO: authenticate who is disconnecting/kicking - /*Pseudocode: - if sender's account index -> client index -> address == sender's address then - continue - end - if sender's account index -> admin == true OR sender's account index -> mod == true then - continue - end - if neither of the above is true, then output a warning to the console, and return - */ +void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) { + //get the account and client data + AccountData* accountData = accountMgr.Get(argPacket->accountIndex); + ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); - //forward to the specified client - network.SendTo( - clientMgr.Get(accountMgr.Get(argPacket->accountIndex)->GetClientIndex())->GetAddress(), - static_cast(argPacket) - ); + if (clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified logout detected targeting: " << accountData->GetUsername() << std::endl; + return; + } - //save and unload this account's characters + //send the logout response + ClientPacket newPacket; + newPacket.type = SerialPacketType::LOGOUT_RESPONSE; + newPacket.clientIndex = accountData->GetClientIndex(); + newPacket.accountIndex = argPacket->accountIndex; + + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); + + //save and unload this accounts characters characterMgr.UnloadIf([&](std::pair it) -> bool { if (argPacket->accountIndex == it.second.GetOwner()) { //pump the unload message to all remaining clients - PumpCharacterUnload(it.first); +// PumpCharacterUnload(it.first); return true; } return false; }); - //erase the in-memory stuff - clientMgr.Unload(accountMgr.Get(argPacket->accountIndex)->GetClientIndex()); + //unload this account accountMgr.Unload(argPacket->accountIndex); //finished this routine - std::cout << "Disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; + std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } -//SET: connections -void ServerApplication::HandleShutdown(ClientPacket* const argPacket) { - //TODO: authenticate who is shutting the server down - /*Pseudocode: - if sender's account -> admin is not true then - print a warning - return - end - */ +void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { + //get the client data + ClientData* clientData = clientMgr.Get(argPacket->clientIndex); + + if (clientData->GetAddress() != argPacket->srcAddress) { + std::cerr << "Falsified disconnection detected targeting: " << argPacket->clientIndex << std::endl; + return; + } + + //send the disconnect response + ClientPacket newPacket; + newPacket.type = SerialPacketType::DISCONNECT_RESPONSE; + newPacket.clientIndex = argPacket->clientIndex; + + network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); + + //TODO: need a method for this redundunt chunk of redundant code + //find and unload the accounts associated with this client + accountMgr.UnloadIf([&](std::pair account) -> bool { + if (account.second.GetClientIndex() == argPacket->clientIndex) { + //find and unload the characters associated with this account + characterMgr.UnloadIf([&](std::pair character) -> bool { + if (character.second.GetOwner() == account.first) { +// PumpCharacterUnload(character.first); + return true; + } + return false; + }); + return true; + } + return false; + }); + + //unload this client + clientMgr.Unload(argPacket->clientIndex); + + //finished this routine + std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; +} + +//------------------------- +//server commands +//------------------------- + +//void ServerApplication::HandleDisconnectForced(ClientPacket* const argPacket) { +// //TODO +//} + +void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { + //get the account and client data + AccountData* accountData = accountMgr.Get(argPacket->accountIndex); + ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); + + if (clientData->GetAddress() != argPacket->srcAddress || accountData->GetAdministrator() != true) { + std::cerr << "Falsified server shutdown detected from: " << accountData->GetUsername() << std::endl; + return; + } //end the server running = false; //disconnect all clients - ClientPacket newPacket; - newPacket.type = SerialPacketType::DISCONNECT_FORCED; - PumpPacket(&newPacket); +// ClientPacket newPacket; +// newPacket.type = SerialPacketType::DISCONNECT_FORCED; +// PumpPacket(&newPacket); //finished this routine std::cout << "Shutdown signal accepted" << std::endl; } +/* + //------------------------- //map management //------------------------- @@ -351,4 +442,7 @@ void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int packet->roomIndex = character->GetRoomIndex(); packet->origin = character->GetOrigin(); packet->motion = character->GetMotion(); -} \ No newline at end of file +} + +//TODO: remove this terminate comment +//*/ \ No newline at end of file