diff --git a/server/accounts/account_manager.cpp b/server/accounts/account_manager.cpp index e16ad3c..fccf530 100644 --- a/server/accounts/account_manager.cpp +++ b/server/accounts/account_manager.cpp @@ -87,13 +87,13 @@ int AccountManager::Load(std::string username, int clientIndex) { int uid = sqlite3_column_int(statement, 0); //check to see if this account is already loaded - if (accountMap.find(uid) != accountMap.end()) { + if (elementMap.find(uid) != elementMap.end()) { sqlite3_finalize(statement); return -1; } //extract the data into memory - AccountData& newAccount = accountMap[uid]; + AccountData& newAccount = elementMap[uid]; newAccount.username = reinterpret_cast(sqlite3_column_text(statement, 1)); newAccount.blackListed = sqlite3_column_int(statement, 2); newAccount.whiteListed = sqlite3_column_int(statement, 3); @@ -121,11 +121,11 @@ int AccountManager::Save(int uid) { //DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID. //this method fails if this account is not loaded - if (accountMap.find(uid) == accountMap.end()) { + if (elementMap.find(uid) == elementMap.end()) { return -1; } - AccountData& account = accountMap[uid]; + AccountData& account = elementMap[uid]; sqlite3_stmt* statement = nullptr; //prep @@ -163,7 +163,7 @@ void AccountManager::Unload(int uid) { //save this user account, and then unload it //NOTE: the associated characters are unloaded externally Save(uid); - accountMap.erase(uid); + elementMap.erase(uid); } void AccountManager::Delete(int uid) { @@ -190,25 +190,27 @@ void AccountManager::Delete(int uid) { //finish the routine sqlite3_finalize(statement); - accountMap.erase(uid); + elementMap.erase(uid); } void AccountManager::UnloadAll() { - for (auto& it : accountMap) { + for (auto& it : elementMap) { Save(it.first); } - accountMap.clear(); + elementMap.clear(); } -void AccountManager::UnloadIf(std::function)> fn) { +void AccountManager::UnloadIf(std::function)> fn) { //replicate std::remove_if, using custom code - for (std::map::iterator it = accountMap.begin(); it != accountMap.end(); /* empty */) { + std::map::iterator it = elementMap.begin(); + while (it != elementMap.end()) { if (fn(*it)) { Save(it->first); - it = accountMap.erase(it); - continue; + it = elementMap.erase(it); + } + else { + ++it; } - ++it; } } @@ -218,9 +220,9 @@ void AccountManager::UnloadIf(std::function)> f AccountData* AccountManager::Get(int uid) { //TODO: could this load an account first? - std::map::iterator it = accountMap.find(uid); + std::map::iterator it = elementMap.find(uid); - if (it == accountMap.end()) { + if (it == elementMap.end()) { return nullptr; } @@ -228,7 +230,7 @@ AccountData* AccountManager::Get(int uid) { } int AccountManager::GetLoadedCount() { - return accountMap.size(); + return elementMap.size(); } int AccountManager::GetTotalCount() { @@ -250,7 +252,7 @@ int AccountManager::GetTotalCount() { } std::map* AccountManager::GetContainer() { - return &accountMap; + return &elementMap; } sqlite3* AccountManager::SetDatabase(sqlite3* db) { diff --git a/server/accounts/account_manager.hpp b/server/accounts/account_manager.hpp index 327eb3a..e1bb576 100644 --- a/server/accounts/account_manager.hpp +++ b/server/accounts/account_manager.hpp @@ -24,29 +24,33 @@ #include "account_data.hpp" #include "singleton.hpp" +#include "manager_interface.hpp" #include "sqlite3/sqlite3.h" #include #include -class AccountManager : public Singleton { +class AccountManager: + public Singleton, + public ManagerInterface +{ public: - //public access methods - int Create(std::string username, int clientIndex); - int Load(std::string username, int clientIndex); - int Save(int uid); - void Unload(int uid); - void Delete(int uid); + //common public methods + int Create(std::string username, int clientIndex) override; + int Load(std::string username, int clientIndex) override; + int Save(int uid) override; + void Unload(int uid) override; + void Delete(int uid) override; - void UnloadAll(); - void UnloadIf(std::function)> fn); + void UnloadAll() override; + void UnloadIf(std::function)> fn) override; //accessors and mutators - AccountData* Get(int uid); - int GetLoadedCount(); - int GetTotalCount(); - std::map* GetContainer(); + AccountData* Get(int uid) override; + int GetLoadedCount() override; + int GetTotalCount() override; + std::map* GetContainer() override; sqlite3* SetDatabase(sqlite3* db); sqlite3* GetDatabase(); @@ -57,7 +61,6 @@ private: AccountManager() = default; ~AccountManager() = default; - std::map accountMap; sqlite3* database = nullptr; }; diff --git a/server/accounts/makefile b/server/accounts/makefile index f24e1ba..2a5c671 100644 --- a/server/accounts/makefile +++ b/server/accounts/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../../common/utilities +INCLUDES+=. ../server_utilities ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/characters/character_manager.cpp b/server/characters/character_manager.cpp index 080b0ea..a9079b3 100644 --- a/server/characters/character_manager.cpp +++ b/server/characters/character_manager.cpp @@ -98,7 +98,7 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) { int uid = sqlite3_column_int(statement, 0); //check to see if this character is already loaded - if (characterMap.find(uid) != characterMap.end()) { + if (elementMap.find(uid) != elementMap.end()) { sqlite3_finalize(statement); return -1; } @@ -110,7 +110,7 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) { } //extract the data into memory - CharacterData& newChar = characterMap[uid]; + CharacterData& newChar = elementMap[uid]; //metadata newChar.owner = owner; @@ -145,11 +145,11 @@ int CharacterManager::Save(int uid) { //DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID. //this method fails if this character is not loaded - if (characterMap.find(uid) == characterMap.end()) { + if (elementMap.find(uid) == elementMap.end()) { return -1; } - CharacterData& character = characterMap[uid]; + CharacterData& character = elementMap[uid]; sqlite3_stmt* statement = nullptr; //prep @@ -187,7 +187,7 @@ int CharacterManager::Save(int uid) { void CharacterManager::Unload(int uid) { //save this character, then unload it Save(uid); - characterMap.erase(uid); + elementMap.erase(uid); } void CharacterManager::Delete(int uid) { @@ -213,25 +213,26 @@ void CharacterManager::Delete(int uid) { //finish the routine sqlite3_finalize(statement); - characterMap.erase(uid); + elementMap.erase(uid); } void CharacterManager::UnloadAll() { - for (auto& it : characterMap) { + for (auto& it : elementMap) { Save(it.first); } - characterMap.clear(); + elementMap.clear(); } -void CharacterManager::UnloadIf(std::function)> fn) { - //replicate std::remove_if, using custom code - for (std::map::iterator it = characterMap.begin(); it != characterMap.end(); /* empty */) { +void CharacterManager::UnloadIf(std::function)> fn) { + std::map::iterator it = elementMap.begin(); + while (it != elementMap.end()) { if (fn(*it)) { Save(it->first); - it = characterMap.erase(it); - continue; + it = elementMap.erase(it); + } + else { + ++it; } - ++it; } } @@ -240,9 +241,9 @@ void CharacterManager::UnloadIf(std::function //------------------------- CharacterData* CharacterManager::Get(int uid) { - std::map::iterator it = characterMap.find(uid); + std::map::iterator it = elementMap.find(uid); - if (it == characterMap.end()) { + if (it == elementMap.end()) { return nullptr; } @@ -250,7 +251,7 @@ CharacterData* CharacterManager::Get(int uid) { } int CharacterManager::GetLoadedCount() { - return characterMap.size(); + return elementMap.size(); } int CharacterManager::GetTotalCount() { @@ -272,7 +273,7 @@ int CharacterManager::GetTotalCount() { } std::map* CharacterManager::GetContainer() { - return &characterMap; + return &elementMap; } sqlite3* CharacterManager::SetDatabase(sqlite3* db) { diff --git a/server/characters/character_manager.hpp b/server/characters/character_manager.hpp index 68b58aa..d73cd42 100644 --- a/server/characters/character_manager.hpp +++ b/server/characters/character_manager.hpp @@ -24,29 +24,33 @@ #include "character_data.hpp" #include "singleton.hpp" +#include "manager_interface.hpp" #include "sqlite3/sqlite3.h" #include #include -class CharacterManager : public Singleton { +class CharacterManager: + public Singleton, + public ManagerInterface +{ public: - //public access methods - int Create(int owner, std::string handle, std::string avatar); - int Load(int owner, std::string handle, std::string avatar); - int Save(int uid); - void Unload(int uid); - void Delete(int uid); + //common public methods + int Create(int owner, std::string handle, std::string avatar) override; + int Load(int owner, std::string handle, std::string avatar) override; + int Save(int uid) override; + void Unload(int uid) override; + void Delete(int uid) override; - void UnloadAll(); - void UnloadIf(std::function)> fn); + void UnloadAll() override; + void UnloadIf(std::function)> fn) override; //accessors and mutators - CharacterData* Get(int uid); - int GetLoadedCount(); - int GetTotalCount(); - std::map* GetContainer(); + CharacterData* Get(int uid) override; + int GetLoadedCount() override; + int GetTotalCount() override; + std::map* GetContainer() override; sqlite3* SetDatabase(sqlite3* db); sqlite3* GetDatabase(); @@ -57,7 +61,6 @@ private: CharacterManager() = default; ~CharacterManager() = default; - std::map characterMap; sqlite3* database = nullptr; }; diff --git a/server/characters/makefile b/server/characters/makefile index 68368e7..7133d20 100644 --- a/server/characters/makefile +++ b/server/characters/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../../common/gameplay ../../common/utilities +INCLUDES+=. ../server_utilities ../../common/gameplay ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/rooms/makefile b/server/rooms/makefile index ea66828..4b00d80 100644 --- a/server/rooms/makefile +++ b/server/rooms/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../../common/map ../../common/utilities +INCLUDES+=. ../server_utilities ../../common/map ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/rooms/room_api.cpp b/server/rooms/room_api.cpp index 636d206..bc8b1a1 100644 --- a/server/rooms/room_api.cpp +++ b/server/rooms/room_api.cpp @@ -29,21 +29,36 @@ static int getPager(lua_State* L) { return 1; } -static int create(lua_State* L) { - //EMPTY - //NOTE: This can be used to set defaults for the pager +static int setRoomName(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + room->SetRoomName(lua_tostring(L, 2)); return 0; } -static int unload(lua_State* L) { - //EMPTY +static int getRoomName(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushstring(L, room->GetRoomName().c_str()); + return 1; +} + +static int setTilesetName(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + room->SetTilesetName(lua_tostring(L, 2)); return 0; } +static int getTilesetName(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushstring(L, room->GetTilesetName().c_str()); + return 1; +} + static const luaL_Reg roomLib[] = { {"GetPager",getPager}, - {"Create", create}, - {"Unload", unload}, + {"SetRoomName", setRoomName}, + {"GetRoomName", getRoomName}, + {"SetTileset", setTilesetName}, + {"GetTileset", getTilesetName}, {nullptr, nullptr} }; diff --git a/server/rooms/room_data.hpp b/server/rooms/room_data.hpp index 1ced1be..046b119 100644 --- a/server/rooms/room_data.hpp +++ b/server/rooms/room_data.hpp @@ -35,6 +35,9 @@ public: //accessors and mutators RegionPagerLua* GetPager() { return &pager; } + std::string SetRoomName(std::string s) { return roomName = s; } + std::string GetRoomName() { return roomName; } + std::string SetTilesetName(std::string s) { return tilesetName = s; } std::string GetTilesetName() { return tilesetName; } @@ -43,7 +46,10 @@ private: //members RegionPagerLua pager; + std::string roomName; std::string tilesetName; + //TODO: pass the room name & tileset name to the clients + //TODO: lua references i.e. create, unload, etc. }; #endif diff --git a/server/rooms/room_manager.cpp b/server/rooms/room_manager.cpp index 4560fe9..a697201 100644 --- a/server/rooms/room_manager.cpp +++ b/server/rooms/room_manager.cpp @@ -29,78 +29,76 @@ //public access methods //------------------------- -int RoomManager::CreateRoom() { +int RoomManager::Create() { //create the room - RoomData* newRoom = new RoomData(); - newRoom->pager.SetLuaState(luaState); - - //register the room - roomMap[counter] = newRoom; - - //API hook - lua_getglobal(luaState, TORTUGA_ROOM_NAME); - lua_getfield(luaState, -1, "Create"); - lua_pushlightuserdata(luaState, newRoom); - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); - } - lua_pop(luaState, 1); + RoomData* newRoom = &elementMap[counter]; //implicitly constructs the element + newRoom->pager.SetLuaState(lua); //finish the routine return counter++; } -void RoomManager::UnloadRoom(int uid) { +int RoomManager::Load() { + //TODO: RoomManager::Load() + return -1; +} + +int RoomManager::Save(int uid) { + //TODO: RoomManager::Save(uid) + return -1; +} + +void RoomManager::Unload(int uid) { //find the room - RoomData* room = FindRoom(uid); - if (!room) { + std::map::iterator it = elementMap.find(uid); + if (it == elementMap.end()) { return; } - //API hook - lua_getglobal(luaState, TORTUGA_ROOM_NAME); - lua_getfield(luaState, -1, "Unload"); - lua_pushlightuserdata(luaState, room); - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); - } - lua_pop(luaState, 1); - //free the memory - delete room; - roomMap.erase(uid); + elementMap.erase(uid); } -RoomData* RoomManager::GetRoom(int uid) { - return FindRoom(uid); - //TODO: expand this to auto-create the room -} - -RoomData* RoomManager::FindRoom(int uid) { - std::map::iterator it = roomMap.find(uid); - if (it == roomMap.end()) { - return nullptr; - } - return it->second; -} - -int RoomManager::PushRoom(RoomData* room) { - roomMap[counter++] = room; - return counter; +void RoomManager::Delete(int uid) { + //TODO: RoomManager::Delete(int uid) + //NOTE: aliased to RoomManager::Unload(int uid) + Unload(uid); } void RoomManager::UnloadAll() { - lua_getglobal(luaState, TORTUGA_ROOM_NAME); + elementMap.clear(); +} - for (auto& it : roomMap) { - //API hook - lua_getfield(luaState, -1, "Unload"); - lua_pushlightuserdata(luaState, it.second); - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); +void RoomManager::UnloadIf(std::function)> fn) { + std::map::iterator it = elementMap.begin(); + while (it != elementMap.end()) { + if (fn(*it)) { + it = elementMap.erase(it); + } + else { + ++it; } } +} - lua_pop(luaState, 1); - roomMap.clear(); -} \ No newline at end of file +RoomData* RoomManager::Get(int uid) { + std::map::iterator it = elementMap.find(uid); + + if (it == elementMap.end()) { + return nullptr; + } + + return &it->second; +} + +int RoomManager::GetLoadedCount() { + return elementMap.size(); +} + +int RoomManager::GetTotalCount() { + return elementMap.size(); +} + +std::map* RoomManager::GetContainer() { + return &elementMap; +} diff --git a/server/rooms/room_manager.hpp b/server/rooms/room_manager.hpp index 2f13893..5245d9c 100644 --- a/server/rooms/room_manager.hpp +++ b/server/rooms/room_manager.hpp @@ -24,28 +24,34 @@ #include "room_data.hpp" #include "singleton.hpp" +#include "manager_interface.hpp" #include "lua/lua.hpp" -#include - -class RoomManager : public Singleton { +class RoomManager: + public Singleton, + public ManagerInterface +{ public: - //public access methods - int CreateRoom(); - void UnloadRoom(int uid); + //common public methods + int Create() override; + int Load() override; + int Save(int uid) override; + void Unload(int uid) override; + void Delete(int uid) override; - RoomData* GetRoom(int uid); - RoomData* FindRoom(int uid); - int PushRoom(RoomData*); - - void UnloadAll(); + void UnloadAll() override; + void UnloadIf(std::function)> fn) override; //accessors and mutators - std::map* GetContainer() { return &roomMap; } + RoomData* Get(int uid) override; + int GetLoadedCount() override; + int GetTotalCount() override; + std::map* GetContainer() override; - lua_State* SetLuaState(lua_State* L) { return luaState = L; } - lua_State* GetLuaState() { return luaState; } + //hooks + lua_State* SetLuaState(lua_State* L) { return lua = L; } + lua_State* GetLuaState() { return lua; } private: friend Singleton; @@ -53,8 +59,7 @@ private: RoomManager() = default; ~RoomManager() = default; - std::map roomMap; - lua_State* luaState = nullptr; + lua_State* lua = nullptr; int counter = 0; }; diff --git a/server/rooms/room_manager_api.cpp b/server/rooms/room_manager_api.cpp index 02565b9..ab4d6d9 100644 --- a/server/rooms/room_manager_api.cpp +++ b/server/rooms/room_manager_api.cpp @@ -23,34 +23,34 @@ #include "room_manager.hpp" -#include +int createRoom(lua_State* L) { + //create & get the room + RoomManager& roomMgr = RoomManager::GetSingleton(); + int uid = roomMgr.Create(); + RoomData* room = roomMgr.Get(uid); -static int getRoom(lua_State* L) { - //find, push and return the room - RoomData* room = RoomManager::GetSingleton().GetRoom(lua_tointeger(L, -2)); - lua_pushlightuserdata(L, reinterpret_cast(room)); - return 1; + //setup the room + //TODO: room parameters only set via lua, fix this + room->SetRoomName(lua_tostring(L, 1)); + room->SetTilesetName(lua_tostring(L, 2)); + + //return room, uid + lua_pushlightuserdata(L, static_cast(room)); + lua_pushinteger(L, uid); + + return 2; } -static int createRoom(lua_State* L) { - //TODO: check parameter count for the glue functions - - //create, find and return the room - int uid = RoomManager::GetSingleton().CreateRoom(); - lua_pushlightuserdata(L, RoomManager::GetSingleton().FindRoom(uid)); - return 1; -} - -static int unloadRoom(lua_State* L) { - //unload the specified room - RoomManager::GetSingleton().UnloadRoom(lua_tointeger(L, -2)); +int unloadRoom(lua_State* L) { + //TODO: check authorization for room deletion + RoomManager& roomMgr = RoomManager::GetSingleton(); + roomMgr.Unload(lua_tointeger(L, 1)); return 0; } static const luaL_Reg roomManagerLib[] = { - {"GetRoom",getRoom}, - {"CreateRoom",createRoom}, - {"UnloadRoom",unloadRoom}, + {"CreateRoom", createRoom}, + {"UnloadRoom", unloadRoom}, {nullptr, nullptr} }; diff --git a/server/server_methods.cpp b/server/server_methods.cpp index b211d8f..79f8d46 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -161,7 +161,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { newPacket.y = argPacket->y; //BUG: possibly related to #35 - newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y); + newPacket.region = roomMgr.Get(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y); //send the content network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); diff --git a/server/server_utilities/manager_interface.hpp b/server/server_utilities/manager_interface.hpp new file mode 100644 index 0000000..8a5161f --- /dev/null +++ b/server/server_utilities/manager_interface.hpp @@ -0,0 +1,55 @@ +/* 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 MANAGERINTERFACE_HPP_ +#define MANAGERINTERFACE_HPP_ + +#include +#include + +template +class ManagerInterface { +public: + //common public methods + virtual int Create(Arguments... parameters) = 0; + virtual int Load(Arguments... parameters) = 0; + virtual int Save(int uid) = 0; + virtual void Unload(int uid) = 0; + virtual void Delete(int uid) = 0; + + virtual void UnloadAll() = 0; + virtual void UnloadIf(std::function)> fn) = 0; + + //accessors & mutators + virtual T* Get(int uid) = 0; + virtual int GetLoadedCount() = 0; + virtual int GetTotalCount() = 0; //can be an alias of GetLoadedCount() + virtual std::map* GetContainer() = 0; + +protected: + ManagerInterface() = default; + ~ManagerInterface() = default; + + //members + std::map elementMap; +}; + +#endif \ No newline at end of file