From 01244005e9746d5b51d65bcee8d3a901b06f6ceb Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 13 May 2014 00:09:37 +1000 Subject: [PATCH 1/3] Minor file renaming and tweaks --- client/scenes/in_world.cpp | 4 +++ common/network/serial_packet.hpp | 4 ++- .../sql_utility.cpp | 2 +- .../sql_utility.hpp | 0 ..._management.cpp => account_management.cpp} | 2 ++ ...anagement.cpp => character_management.cpp} | 0 server/combat_instance.hpp | 30 ------------------- server/server_application.hpp | 2 -- server/server_internals.cpp | 3 +- todo.txt | 4 ++- 10 files changed, 14 insertions(+), 37 deletions(-) rename server/server_utility.cpp => common/sql_utility.cpp (98%) rename server/server_utility.hpp => common/sql_utility.hpp (100%) rename server/{server_account_management.cpp => account_management.cpp} (99%) rename server/{server_character_management.cpp => character_management.cpp} (100%) delete mode 100644 server/combat_instance.hpp diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 1f4538b..28e7ce5 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -367,7 +367,9 @@ void InWorld::RequestDisconnect() { //send a disconnect request packet.meta.type = SerialPacket::Type::DISCONNECT; + packet.clientInfo.clientIndex = clientIndex; packet.clientInfo.accountIndex = accountIndex; + packet.clientInfo.characterIndex = characterIndex; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); } @@ -378,7 +380,9 @@ void InWorld::RequestShutDown() { //send a shutdown request packet.meta.type = SerialPacket::Type::SHUTDOWN; + packet.clientInfo.clientIndex = clientIndex; packet.clientInfo.accountIndex = accountIndex; + packet.clientInfo.characterIndex = characterIndex; serialize(&packet, buffer); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); } diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 29f4af1..3b8c4e5 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -27,7 +27,7 @@ #include "SDL/SDL_net.h" -#define NETWORK_VERSION 20140506 +#define NETWORK_VERSION 20140512 #define PACKET_STRING_SIZE 100 #pragma pack(push, 0) @@ -42,6 +42,8 @@ union SerialPacket { PING = 1, PONG = 2, + //TODO: rejection message + //Searching for a server to join BROADCAST_REQUEST = 3, BROADCAST_RESPONSE = 4, diff --git a/server/server_utility.cpp b/common/sql_utility.cpp similarity index 98% rename from server/server_utility.cpp rename to common/sql_utility.cpp index 8ef171f..5d586d4 100644 --- a/server/server_utility.cpp +++ b/common/sql_utility.cpp @@ -19,7 +19,7 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "server_utility.hpp" +#include "sql_utility.hpp" #include "utility.hpp" diff --git a/server/server_utility.hpp b/common/sql_utility.hpp similarity index 100% rename from server/server_utility.hpp rename to common/sql_utility.hpp diff --git a/server/server_account_management.cpp b/server/account_management.cpp similarity index 99% rename from server/server_account_management.cpp rename to server/account_management.cpp index 761c1e5..3559714 100644 --- a/server/server_account_management.cpp +++ b/server/account_management.cpp @@ -186,6 +186,8 @@ void ServerApplication::DeleteUserAccount(int uid) { throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) ); } + //TODO: delete this account's characters? + //finish the routine sqlite3_finalize(statement); accountMap.erase(uid); diff --git a/server/server_character_management.cpp b/server/character_management.cpp similarity index 100% rename from server/server_character_management.cpp rename to server/character_management.cpp diff --git a/server/combat_instance.hpp b/server/combat_instance.hpp deleted file mode 100644 index 9f4dedb..0000000 --- a/server/combat_instance.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2014 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#ifndef COMBATINSTANCE_HPP_ -#define COMBATINSTANCE_HPP_ - -struct CombatInstance { - //uid - static int uidCounter; -}; - -#endif diff --git a/server/server_application.hpp b/server/server_application.hpp index 1b0cd60..5925ccd 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -26,7 +26,6 @@ #include "client_data.hpp" #include "account_data.hpp" #include "character_data.hpp" -#include "combat_instance.hpp" //maps #include "map_allocator.hpp" @@ -102,7 +101,6 @@ private: std::map clientMap; std::map accountMap; std::map characterMap; - std::map combatMap; //maps //TODO: I need to handle multiple map objects diff --git a/server/server_internals.cpp b/server/server_internals.cpp index d4fd93b..3432618 100644 --- a/server/server_internals.cpp +++ b/server/server_internals.cpp @@ -21,7 +21,7 @@ */ #include "server_application.hpp" -#include "server_utility.hpp" +#include "sql_utility.hpp" #include #include @@ -33,7 +33,6 @@ int ClientData::uidCounter = 0; int CharacterData::uidCounter = 0; -int CombatInstance::uidCounter = 0; //------------------------- //Define the public members diff --git a/todo.txt b/todo.txt index d232e7d..c37d3e4 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,6 @@ -I need to keep the documentation up to date. Namely, the GDD is getting out of date. +* I need to keep the documentation up to date. Namely, the GDD is getting out of date. +* How many lookups is the map system using? +* Add the serial packet to the network utility --Naming conventions-- From eeb2400e79e2df449397c5b9e64d88d9c6b5d18a Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 13 May 2014 02:09:00 +1000 Subject: [PATCH 2/3] Rearranged the server-side object hierarchy (read more) This has been a long-running problem for days, but I've finally implemented a correctly working hierarchy between the ClientData, AccountData and CharacterData objects: CharacterData -> AccountData -> ClientData There doesn't seem to be any issues with it right now, touch wood. --- server/account_data.hpp | 1 - server/account_management.cpp | 9 +++-- server/character_data.hpp | 3 -- server/character_management.cpp | 1 + server/server_application.hpp | 4 +-- server/server_connections.cpp | 58 ++++++++++++++++++++------------- server/server_internals.cpp | 1 - 7 files changed, 42 insertions(+), 35 deletions(-) diff --git a/server/account_data.hpp b/server/account_data.hpp index f439c61..7ebc98c 100644 --- a/server/account_data.hpp +++ b/server/account_data.hpp @@ -31,7 +31,6 @@ struct AccountData { bool whiteListed = true; int clientIndex; - int characterIndex; }; #endif diff --git a/server/account_management.cpp b/server/account_management.cpp index 3559714..4cb201a 100644 --- a/server/account_management.cpp +++ b/server/account_management.cpp @@ -38,7 +38,7 @@ static const char* DELETE_USER_ACCOUNT = "DELETE FROM UserAccounts WHERE uid = ? //Define the methods //------------------------- -int ServerApplication::CreateUserAccount(std::string username, int clientIndex, int characterIndex) { +int ServerApplication::CreateUserAccount(std::string username, int clientIndex) { //create this user account, failing if it exists, leave this account in memory sqlite3_stmt* statement = nullptr; @@ -62,10 +62,10 @@ int ServerApplication::CreateUserAccount(std::string username, int clientIndex, sqlite3_finalize(statement); //load this account into memory - return LoadUserAccount(username, clientIndex, characterIndex); + return LoadUserAccount(username, clientIndex); } -int ServerApplication::LoadUserAccount(std::string username, int clientIndex, int characterIndex) { +int ServerApplication::LoadUserAccount(std::string username, int clientIndex) { //load this user account, failing if it is in memory, creating it if it doesn't exist sqlite3_stmt* statement = nullptr; @@ -99,7 +99,6 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex, in newAccount.blackListed = sqlite3_column_int(statement, 2); newAccount.whiteListed = sqlite3_column_int(statement, 3); newAccount.clientIndex = clientIndex; - newAccount.characterIndex = characterIndex; //finish the routine sqlite3_finalize(statement); @@ -110,7 +109,7 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex, in if (ret == SQLITE_DONE) { //create the non-existant account instead - return CreateUserAccount(username, clientIndex, characterIndex); + return CreateUserAccount(username, clientIndex); } throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) )); diff --git a/server/character_data.hpp b/server/character_data.hpp index f31e185..0442483 100644 --- a/server/character_data.hpp +++ b/server/character_data.hpp @@ -54,9 +54,6 @@ struct CharacterData { float accuracy = 0.0; float evasion = 0.0; float luck = 0.0; - - //uid - static int uidCounter; }; #endif diff --git a/server/character_management.cpp b/server/character_management.cpp index d13d5eb..5e0fa60 100644 --- a/server/character_management.cpp +++ b/server/character_management.cpp @@ -110,6 +110,7 @@ int ServerApplication::LoadCharacter(int owner, std::string handle, std::string CharacterData& newChar = characterMap[uid]; //metadata + newChar.owner = owner; newChar.handle = reinterpret_cast(sqlite3_column_text(statement, 2)); newChar.avatar = reinterpret_cast(sqlite3_column_text(statement, 3)); //Don't cache the birth diff --git a/server/server_application.hpp b/server/server_application.hpp index 5925ccd..56f1303 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -77,8 +77,8 @@ private: void PumpPacket(SerialPacket); //Account management - int CreateUserAccount(std::string username, int clientIndex, int characterIndex); - int LoadUserAccount(std::string username, int clientIndex, int characterIndex); + int CreateUserAccount(std::string username, int clientIndex); + int LoadUserAccount(std::string username, int clientIndex); int SaveUserAccount(int uid); void UnloadUserAccount(int uid); void DeleteUserAccount(int uid); diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 0d8eead..a311ba5 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -42,29 +42,32 @@ void ServerApplication::HandleBroadcastRequest(SerialPacket packet) { } void ServerApplication::HandleJoinRequest(SerialPacket packet) { + //create the new client + ClientData newClient; + newClient.address = packet.meta.srcAddress; + //load the user account - int accountIndex = LoadUserAccount(packet.clientInfo.username, ClientData::uidCounter, CharacterData::uidCounter); + int accountIndex = LoadUserAccount(packet.clientInfo.username, ClientData::uidCounter); if (accountIndex < 0) { //TODO: send rejection packet std::cerr << "Error: Account already loaded: " << accountIndex << std::endl; return; } - //create the new client - ClientData newClient; - newClient.address = packet.meta.srcAddress; - - //TODO: move this into the character management code - //create the new character - CharacterData newCharacter; - newCharacter.handle = packet.clientInfo.handle; - newCharacter.avatar = packet.clientInfo.avatar; + //load the new character + int characterIndex = LoadCharacter(accountIndex, packet.clientInfo.handle, packet.clientInfo.avatar); + if (characterIndex < 0) { + //TODO: send rejection packet + std::cerr << "Error: Character already loaded: " << characterIndex << std::endl; + UnloadUserAccount(accountIndex); + return; + } //send the client their info packet.meta.type = SerialPacket::Type::JOIN_RESPONSE; packet.clientInfo.clientIndex = ClientData::uidCounter; packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = CharacterData::uidCounter; + packet.clientInfo.characterIndex = characterIndex; //bounce this packet char buffer[PACKET_BUFFER_SIZE]; @@ -73,17 +76,16 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) { //send the new character to all clients packet.meta.type = SerialPacket::Type::CHARACTER_NEW; - packet.characterInfo.characterIndex = CharacterData::uidCounter; - strncpy(packet.characterInfo.handle, newCharacter.handle.c_str(), PACKET_STRING_SIZE); - strncpy(packet.characterInfo.avatar, newCharacter.avatar.c_str(), PACKET_STRING_SIZE); - packet.characterInfo.position = newCharacter.position; - packet.characterInfo.motion = newCharacter.motion; + packet.characterInfo.characterIndex = characterIndex; + strncpy(packet.characterInfo.handle, characterMap[characterIndex].handle.c_str(), PACKET_STRING_SIZE); + strncpy(packet.characterInfo.avatar, characterMap[characterIndex].avatar.c_str(), PACKET_STRING_SIZE); + packet.characterInfo.position = characterMap[characterIndex].position; + packet.characterInfo.motion = characterMap[characterIndex].motion; PumpPacket(packet); //TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?) //finished this routine clientMap[ClientData::uidCounter++] = newClient; - characterMap[CharacterData::uidCounter++] = newCharacter; std::cout << "Connect, total: " << clientMap.size() << std::endl; } @@ -111,26 +113,36 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) { void ServerApplication::HandleDisconnect(SerialPacket packet) { //TODO: authenticate who is disconnecting/kicking - //TODO: define the difference between unloading and deletng a character + //TODO: define the difference between unloading and deleting a character //forward to the specified client char buffer[PACKET_BUFFER_SIZE]; serialize(&packet, buffer); network.Send(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, buffer, PACKET_BUFFER_SIZE); - //delete the client side character + //delete the server- and client-side character(s) SerialPacket delPacket; delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; - delPacket.characterInfo.characterIndex = accountMap[packet.clientInfo.accountIndex].characterIndex; - PumpPacket(delPacket); + + for (std::map::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) { + if (it->second.owner == packet.clientInfo.accountIndex) { + delPacket.characterInfo.characterIndex = it->first; + PumpPacket(delPacket); + SaveCharacter(it->first); + it = characterMap.erase(it); //efficient + continue; + } + else { + ++it; + } + } //erase the in-memory stuff clientMap.erase(accountMap[packet.clientInfo.accountIndex].clientIndex); - characterMap.erase(accountMap[packet.clientInfo.accountIndex].characterIndex); UnloadUserAccount(packet.clientInfo.accountIndex); //finished this routine - std::cout << "Disconnect, total: " << accountMap.size() << std::endl; + std::cout << "Disconnect, total: " << clientMap.size() << std::endl; } void ServerApplication::HandleShutdown(SerialPacket packet) { diff --git a/server/server_internals.cpp b/server/server_internals.cpp index 3432618..ee7446b 100644 --- a/server/server_internals.cpp +++ b/server/server_internals.cpp @@ -32,7 +32,6 @@ //------------------------- int ClientData::uidCounter = 0; -int CharacterData::uidCounter = 0; //------------------------- //Define the public members From 68475eee0f6891cd56b0d2a77f5155b447471dd1 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 13 May 2014 02:51:50 +1000 Subject: [PATCH 3/3] Created PumpCharacterUnload --- rsc/scripts/setup_server.sql | 1 + server/account_management.cpp | 5 ++--- server/server_application.hpp | 1 + server/server_connections.cpp | 17 ++++++++++------- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index 2c5c018..7a84df0 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -9,6 +9,7 @@ CREATE TABLE IF NOT EXISTS UserAccounts ( -- password varchar(100), blacklisted BIT DEFAULT 0, whitelisted BIT DEFAULT 1 +-- TODO: moderator ); ------------------------- diff --git a/server/account_management.cpp b/server/account_management.cpp index 4cb201a..5f82e55 100644 --- a/server/account_management.cpp +++ b/server/account_management.cpp @@ -159,13 +159,14 @@ int ServerApplication::SaveUserAccount(int uid) { void ServerApplication::UnloadUserAccount(int uid) { //save this user account, and then unload it + //NOTE: the associated characters are unloaded externally SaveUserAccount(uid); accountMap.erase(uid); - //TODO: unload this account's characters? } void ServerApplication::DeleteUserAccount(int uid) { //delete a user account from the database, and remove it from memory + //NOTE: the associated characters are unloaded externally sqlite3_stmt* statement = nullptr; //prep @@ -185,8 +186,6 @@ void ServerApplication::DeleteUserAccount(int uid) { throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) ); } - //TODO: delete this account's characters? - //finish the routine sqlite3_finalize(statement); accountMap.erase(uid); diff --git a/server/server_application.hpp b/server/server_application.hpp index 56f1303..0b93372 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -75,6 +75,7 @@ private: //TODO: a function that only sends to characters in a certain proximity void PumpPacket(SerialPacket); + void PumpCharacterUnload(int uid); //Account management int CreateUserAccount(std::string username, int clientIndex); diff --git a/server/server_connections.cpp b/server/server_connections.cpp index a311ba5..4b3bf0f 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -113,21 +113,16 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) { void ServerApplication::HandleDisconnect(SerialPacket packet) { //TODO: authenticate who is disconnecting/kicking - //TODO: define the difference between unloading and deleting a character //forward to the specified client char buffer[PACKET_BUFFER_SIZE]; serialize(&packet, buffer); network.Send(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, buffer, PACKET_BUFFER_SIZE); - //delete the server- and client-side character(s) - SerialPacket delPacket; - delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; - + //unload client and server-side characters for (std::map::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) { if (it->second.owner == packet.clientInfo.accountIndex) { - delPacket.characterInfo.characterIndex = it->first; - PumpPacket(delPacket); + PumpCharacterUnload(it->first); SaveCharacter(it->first); it = characterMap.erase(it); //efficient continue; @@ -191,3 +186,11 @@ void ServerApplication::PumpPacket(SerialPacket packet) { network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE); } } + +void ServerApplication::PumpCharacterUnload(int uid) { + //delete the client-side character(s) + SerialPacket delPacket; + delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; + delPacket.characterInfo.characterIndex = uid; + PumpPacket(delPacket); +} \ No newline at end of file