diff --git a/server/client_data.cpp b/server/account_data.hpp similarity index 81% rename from server/client_data.cpp rename to server/account_data.hpp index d05f95c..220d831 100644 --- a/server/client_data.cpp +++ b/server/account_data.hpp @@ -19,6 +19,18 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "client_data.hpp" +#ifndef ACCOUNTDATA_HPP_ +#define ACCOUNTDATA_HPP_ -int ClientData::uidCounter = 0; +#include + +struct AccountData { + std::string username; + //password + bool blackListed = false; + bool whiteListed = true; + + int clientIndex; +}; + +#endif diff --git a/server/character_data.hpp b/server/character_data.hpp index 5cdad1c..3a12f36 100644 --- a/server/character_data.hpp +++ b/server/character_data.hpp @@ -31,7 +31,6 @@ struct CharacterData { //metadata int clientIndex; - std::string username; std::string handle; std::string avatar; diff --git a/server/character_data.cpp b/server/combat_instance.hpp similarity index 88% rename from server/character_data.cpp rename to server/combat_instance.hpp index 6761b2c..9f4dedb 100644 --- a/server/character_data.cpp +++ b/server/combat_instance.hpp @@ -19,6 +19,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "character_data.hpp" +#ifndef COMBATINSTANCE_HPP_ +#define COMBATINSTANCE_HPP_ -int CharacterData::uidCounter = 0; +struct CombatInstance { + //uid + static int uidCounter; +}; + +#endif diff --git a/server/server_application.hpp b/server/server_application.hpp index a465707..c2114d2 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -24,7 +24,9 @@ //server specific stuff #include "client_data.hpp" +#include "account_data.hpp" #include "character_data.hpp" +#include "combat_instance.hpp" //maps #include "map_allocator.hpp" @@ -75,6 +77,12 @@ private: void PumpPacket(SerialPacket); //TODO: manage the database + int CreateUserAccount(std::string username, int clientIndex); + int LoadUserAccount(std::string username, int clientIndex); + void SaveUserAccount(std::string username); + void UnloadUserAccount(std::string username); + void DeleteUserAccount(std::string username); + //TODO: combat systems //APIs @@ -84,7 +92,9 @@ private: //server tables 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_connections.cpp b/server/server_connections.cpp index f43eb80..0876fb1 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -46,11 +46,17 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) { ClientData newClient; newClient.address = packet.meta.srcAddress; + //debug + std::cout << "Function Return: " << LoadUserAccount(packet.clientInfo.username, ClientData::uidCounter) << std::endl; + + for (auto& it : accountMap) { + std::cout << "Account(" << it.first << "): " << it.second.username << std::endl; + } + //TODO: move this into the character management code //create the new character CharacterData newCharacter; newCharacter.clientIndex = ClientData::uidCounter; - newCharacter.username = packet.clientInfo.username; newCharacter.handle = packet.clientInfo.handle; newCharacter.avatar = packet.clientInfo.avatar; diff --git a/server/server_database.cpp b/server/server_database.cpp new file mode 100644 index 0000000..2ec01b0 --- /dev/null +++ b/server/server_database.cpp @@ -0,0 +1,120 @@ +/* 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. +*/ +#include "server_application.hpp" + +#include "sqlite3/sqlite3.h" + +#include +#include + +//------------------------- +//Define the queries +//------------------------- + +static const char* CREATE_USER_ACCOUNT = "INSERT INTO UserAccounts (username) VALUES (?);"; +static const char* LOAD_USER_ACCOUNT = "SELECT uid, username, blacklisted, whitelisted FROM UserAccounts WHERE username = ?;"; + +//------------------------- +//Define the methods +//------------------------- + +int ServerApplication::CreateUserAccount(std::string username, int clientIndex) { + std::cout << "Calling CreateUserAccount(" << username << ")\n"; + //create this user account, failing if it exists, leave this account in memory + sqlite3_stmt* statement = nullptr; + + //prep + if (sqlite3_prepare_v2(database, CREATE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) { + throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) ); + } + + //parameter + if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) { + throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) ); + } + + //execute + if (sqlite3_step(statement) != SQLITE_DONE) { + //if this returns something, than this account exists + sqlite3_finalize(statement); + return -1; + } + + sqlite3_finalize(statement); + + //load this account into memory + return LoadUserAccount(username, clientIndex); +} + +int ServerApplication::LoadUserAccount(std::string username, int clientIndex) { + std::cout << "Calling LoadUserAccount(" << username << ")\n"; + //load this user account, creating it if it doesn't exist + sqlite3_stmt* statement = nullptr; + + //prep + if (sqlite3_prepare_v2(database, LOAD_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) { + throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) ); + } + + //parameter + if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) { + throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) ); + } + + //execute + int ret = sqlite3_step(statement); + + //process the result + if (ret == SQLITE_ROW) { + std::cout << "ret = ROW\n"; + //extract the data into memory + int uid = sqlite3_column_int(statement, 0); + accountMap[uid].username = reinterpret_cast(sqlite3_column_text(statement, 1)); + accountMap[uid].blackListed = sqlite3_column_int(statement, 2); + accountMap[uid].whiteListed = sqlite3_column_int(statement, 3); + accountMap[uid].clientIndex = clientIndex; + return uid; + } + + if (ret == SQLITE_DONE) { + std::cout << "ret = DONE\n"; + //create the non-existant account instead + return CreateUserAccount(username, clientIndex); + } + + throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) )); +} + +void ServerApplication::SaveUserAccount(std::string username) { + //save this user account, replacing it if it exists + //TODO +} + +void ServerApplication::UnloadUserAccount(std::string username) { + //save this user account, and then unload it + //TODO +} + +void ServerApplication::DeleteUserAccount(std::string username) { + //delete a user account from the database, and remove it from memory + //TODO +} diff --git a/server/server_internals.cpp b/server/server_internals.cpp index f3ad870..d4fd93b 100644 --- a/server/server_internals.cpp +++ b/server/server_internals.cpp @@ -27,6 +27,14 @@ #include #include +//------------------------- +//Define the various UIDs +//------------------------- + +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 c392799..3123187 100644 --- a/todo.txt +++ b/todo.txt @@ -28,3 +28,10 @@ These interact with the database file, making the server a persistent system. * UnloadCharacter * DeleteCharacter +--Battle System-- + +CombatPortal: + x, y + list + list + //... \ No newline at end of file