diff --git a/client/character.cpp b/client/character.cpp index eaa38d8..70ee4a9 100644 --- a/client/character.cpp +++ b/client/character.cpp @@ -21,14 +21,14 @@ */ #include "character.hpp" -void Character::Update(double delta) { +void Character::Update() { if (motion.x && motion.y) { - origin += motion * delta * CHARACTER_WALKING_MOD; + origin += motion * CHARACTER_WALKING_MOD; } else if (motion != 0) { - origin += motion * delta; + origin += motion; } - sprite.Update(delta); + sprite.Update(0.016); } void Character::DrawTo(SDL_Surface* const dest, int camX, int camY) { diff --git a/client/character.hpp b/client/character.hpp index bde4268..23924a4 100644 --- a/client/character.hpp +++ b/client/character.hpp @@ -40,7 +40,7 @@ public: Character() = default; ~Character() = default; - void Update(double delta); + void Update(); //graphics void DrawTo(SDL_Surface* const, int camX, int camY); diff --git a/client/client_application.cpp b/client/client_application.cpp index 16ad96c..75a9d9b 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -120,7 +120,6 @@ void ClientApplication::Proc() { //prepare the time system typedef std::chrono::steady_clock Clock; - std::chrono::duration delta(16); Clock::time_point simTime = Clock::now(); Clock::time_point realTime; @@ -138,8 +137,9 @@ void ClientApplication::Proc() { //simulate game time while (simTime < realTime) { //call each user defined function - activeScene->RunFrame(double(delta.count()) / std::chrono::duration::period::den); - simTime += delta; + activeScene->RunFrame(); + //~60 FPS + simTime += std::chrono::duration(16); } //draw the game to the screen diff --git a/client/scenes/base_scene.cpp b/client/scenes/base_scene.cpp index 48512ec..d4b7824 100644 --- a/client/scenes/base_scene.cpp +++ b/client/scenes/base_scene.cpp @@ -75,10 +75,10 @@ SceneList BaseScene::GetNextScene() const { //Frame loop //------------------------- -void BaseScene::RunFrame(double delta) { +void BaseScene::RunFrame() { FrameStart(); HandleEvents(); - Update(delta); + Update(); FrameEnd(); } @@ -86,6 +86,7 @@ void BaseScene::RenderFrame() { SDL_FillRect(screen, 0, 0); Render(screen); SDL_Flip(screen); + SDL_Delay(10); } //------------------------- diff --git a/client/scenes/base_scene.hpp b/client/scenes/base_scene.hpp index a4bfd88..d954ca0 100644 --- a/client/scenes/base_scene.hpp +++ b/client/scenes/base_scene.hpp @@ -40,13 +40,13 @@ public: SceneList GetNextScene() const; //Frame loop - virtual void RunFrame(double delta); + virtual void RunFrame(); virtual void RenderFrame(); protected: virtual void FrameStart() {} virtual void HandleEvents(); - virtual void Update(double delta) {} + virtual void Update() {} virtual void FrameEnd() {} virtual void Render(SDL_Surface* const screen) {} diff --git a/client/scenes/clean_up.cpp b/client/scenes/clean_up.cpp index 416a1c8..1be9e5c 100644 --- a/client/scenes/clean_up.cpp +++ b/client/scenes/clean_up.cpp @@ -80,22 +80,15 @@ CleanUp::~CleanUp() { //Frame loop //------------------------- -void CleanUp::Update(double delta) { +void CleanUp::Update() { if (std::chrono::steady_clock::now() - startTick > std::chrono::duration(10)) { - QuitEvent(); + SetNextScene(SceneList::MAINMENU); } //BUGFIX: Eat incoming packets while(network.Receive()); } -void CleanUp::RenderFrame() { - SDL_FillRect(GetScreen(), 0, 0); - Render(GetScreen()); - SDL_Flip(GetScreen()); - fps.Calculate(); -} - void CleanUp::Render(SDL_Surface* const screen) { backButton.DrawTo(screen); font.DrawStringTo("You have been disconnected.", screen, 50, 30); diff --git a/client/scenes/clean_up.hpp b/client/scenes/clean_up.hpp index ac39b44..a408d3d 100644 --- a/client/scenes/clean_up.hpp +++ b/client/scenes/clean_up.hpp @@ -30,12 +30,8 @@ #include "raster_font.hpp" #include "button.hpp" -//common -#include "frame_rate.hpp" - -#include "character.hpp" - //client +#include "character.hpp" #include "base_scene.hpp" //std namespace @@ -54,8 +50,7 @@ public: protected: //Frame loop - void Update(double delta); - void RenderFrame(); + void Update(); void Render(SDL_Surface* const); //Event handlers @@ -79,7 +74,6 @@ protected: //UI Button backButton; - FrameRate fps; //auto return std::chrono::steady_clock::time_point startTick; diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index ff0f67b..f78103f 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -92,17 +92,17 @@ void InWorld::FrameStart() { // } -void InWorld::Update(double delta) { +void InWorld::Update() { //suck in and process all waiting packets - SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); + SerialPacket* packetBuffer = reinterpret_cast(new char[MAX_PACKET_SIZE]); while(network.Receive(packetBuffer)) { HandlePacket(packetBuffer); } - free(static_cast(packetBuffer)); + delete reinterpret_cast(packetBuffer); //update the characters for (auto& it : characterMap) { - it.second.Update(delta); + it.second.Update(); } //check the map @@ -129,7 +129,7 @@ void InWorld::Update(double delta) { } if ((localCharacter->GetOrigin() + localCharacter->GetBounds()).CheckOverlap(wallBounds)) { - localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion() * delta)); + localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion())); localCharacter->SetMotion({0,0}); localCharacter->CorrectSprite(); SendPlayerUpdate(); @@ -312,7 +312,12 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { newCharacter.SetOrigin(argPacket->origin); newCharacter.SetMotion(argPacket->motion); - newCharacter.SetBounds({0, 16, 32, 32}); //TODO: magic numbers, fix this + newCharacter.SetBounds({ + CHARACTER_BOUNDS_X, + CHARACTER_BOUNDS_Y, + CHARACTER_BOUNDS_WIDTH, + CHARACTER_BOUNDS_HEIGHT + }); (*newCharacter.GetStats()) = argPacket->stats; diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index c72ff73..e263bc8 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -59,7 +59,7 @@ public: protected: //Frame loop void FrameStart(); - void Update(double delta); + void Update(); void FrameEnd(); void RenderFrame(); void Render(SDL_Surface* const); diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index d866159..80504c3 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -82,13 +82,13 @@ void LobbyMenu::FrameStart() { // } -void LobbyMenu::Update(double delta) { +void LobbyMenu::Update() { //suck in and process all waiting packets - SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); + SerialPacket* packetBuffer = reinterpret_cast(new char[MAX_PACKET_SIZE]); while(network.Receive(packetBuffer)) { HandlePacket(packetBuffer); } - free(static_cast(packetBuffer)); + delete reinterpret_cast(packetBuffer); } void LobbyMenu::FrameEnd() { diff --git a/client/scenes/lobby_menu.hpp b/client/scenes/lobby_menu.hpp index 7020ac8..03160c2 100644 --- a/client/scenes/lobby_menu.hpp +++ b/client/scenes/lobby_menu.hpp @@ -47,7 +47,7 @@ public: protected: //Frame loop void FrameStart(); - void Update(double delta); + void Update(); void FrameEnd(); void Render(SDL_Surface* const); diff --git a/client/scenes/main_menu.cpp b/client/scenes/main_menu.cpp index ca82ef8..5aa431b 100644 --- a/client/scenes/main_menu.cpp +++ b/client/scenes/main_menu.cpp @@ -72,7 +72,7 @@ void MainMenu::FrameStart() { // } -void MainMenu::Update(double delta) { +void MainMenu::Update() { // } diff --git a/client/scenes/main_menu.hpp b/client/scenes/main_menu.hpp index 2dec3ae..9572499 100644 --- a/client/scenes/main_menu.hpp +++ b/client/scenes/main_menu.hpp @@ -37,7 +37,7 @@ public: protected: //Frame loop void FrameStart(); - void Update(double delta); + void Update(); void FrameEnd(); void Render(SDL_Surface* const); diff --git a/client/scenes/options_menu.cpp b/client/scenes/options_menu.cpp index 539cd44..7aa2493 100644 --- a/client/scenes/options_menu.cpp +++ b/client/scenes/options_menu.cpp @@ -59,7 +59,7 @@ void OptionsMenu::FrameStart() { // } -void OptionsMenu::Update(double delta) { +void OptionsMenu::Update() { // } diff --git a/client/scenes/options_menu.hpp b/client/scenes/options_menu.hpp index 8570644..5bb3eed 100644 --- a/client/scenes/options_menu.hpp +++ b/client/scenes/options_menu.hpp @@ -38,7 +38,7 @@ public: protected: //Frame loop void FrameStart(); - void Update(double delta); + void Update(); void FrameEnd(); void Render(SDL_Surface* const); diff --git a/client/scenes/splash_screen.cpp b/client/scenes/splash_screen.cpp index 2c3b233..5473d79 100644 --- a/client/scenes/splash_screen.cpp +++ b/client/scenes/splash_screen.cpp @@ -40,7 +40,7 @@ SplashScreen::~SplashScreen() { //Frame loop //------------------------- -void SplashScreen::Update(double delta) { +void SplashScreen::Update() { if (std::chrono::steady_clock::now() - startTick > std::chrono::duration(1)) { SetNextScene(SceneList::MAINMENU); } diff --git a/client/scenes/splash_screen.hpp b/client/scenes/splash_screen.hpp index 9d55c0c..c6440c1 100644 --- a/client/scenes/splash_screen.hpp +++ b/client/scenes/splash_screen.hpp @@ -36,7 +36,7 @@ public: protected: //Frame loop - void Update(double delta); + void Update(); void Render(SDL_Surface* const); //members diff --git a/common/gameplay/character_defines.hpp b/common/gameplay/character_defines.hpp index 1daa1b4..484fcfa 100644 --- a/common/gameplay/character_defines.hpp +++ b/common/gameplay/character_defines.hpp @@ -25,11 +25,13 @@ #include //the speeds that the characters move -constexpr double CHARACTER_WALKING_SPEED = 140.0; +constexpr double CHARACTER_WALKING_SPEED = 2.24; constexpr double CHARACTER_WALKING_MOD = 1.0/sqrt(2.0); -//the bounding boxes for the characters -constexpr double CHARACTER_BOUNDS_WIDTH = 32.0; -constexpr double CHARACTER_BOUNDS_HEIGHT = 32.0; +//the bounds for the character objects, mapped to the default sprites +constexpr int CHARACTER_BOUNDS_X = 0; +constexpr int CHARACTER_BOUNDS_Y = 16; +constexpr int CHARACTER_BOUNDS_WIDTH = 32; +constexpr int CHARACTER_BOUNDS_HEIGHT = 32; #endif diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index 2fd3dbb..0ccb880 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -78,27 +78,6 @@ static int getDepth(lua_State* L) { return 1; } -static int load(lua_State* L) { - //EMPTY - lua_pushboolean(L, false); - return 1; -} - -static int save(lua_State* L) { - //EMPTY - return 0; -} - -static int create(lua_State* L) { - //EMPTY - return 0; -} - -static int unload(lua_State* L) { - //EMPTY - return 0; -} - static const luaL_Reg regionLib[] = { {"SetTile",setTile}, {"GetTile",getTile}, @@ -109,10 +88,6 @@ static const luaL_Reg regionLib[] = { {"GetWidth",getWidth}, {"GetHeight",getHeight}, {"GetDepth",getDepth}, - {"Load",load}, - {"Save",save}, - {"Create",create}, - {"Unload",unload}, {nullptr, nullptr} }; diff --git a/common/map/region_pager_api.cpp b/common/map/region_pager_api.cpp index 3932421..b08ce6c 100644 --- a/common/map/region_pager_api.cpp +++ b/common/map/region_pager_api.cpp @@ -90,16 +90,55 @@ static int unloadRegion(lua_State* L) { return 0; } +static int setOnLoad(lua_State* L) { + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); + luaL_unref(L, LUA_REGISTRYINDEX, pager->GetLoadReference()); + pager->SetLoadReference(luaL_ref(L, LUA_REGISTRYINDEX)); + return 0; +} + +static int setOnSave(lua_State* L) { + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); + luaL_unref(L, LUA_REGISTRYINDEX, pager->GetSaveReference()); + pager->SetSaveReference(luaL_ref(L, LUA_REGISTRYINDEX)); + return 0; +} + +static int setOnCreate(lua_State* L) { + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); + luaL_unref(L, LUA_REGISTRYINDEX, pager->GetCreateReference()); + pager->SetCreateReference(luaL_ref(L, LUA_REGISTRYINDEX)); + return 0; +} + +static int setOnUnload(lua_State* L) { + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); + luaL_unref(L, LUA_REGISTRYINDEX, pager->GetUnloadReference()); + pager->SetUnloadReference(luaL_ref(L, LUA_REGISTRYINDEX)); + return 0; +} + static const luaL_Reg regionPagerLib[] = { + //curry {"SetTile", setTile}, {"GetTile", getTile}, {"SetSolid", setSolid}, {"GetSolid", getSolid}, + + //access and control {"GetRegion", getRegion}, {"LoadRegion", loadRegion}, {"SaveRegion", saveRegion}, {"CreateRegion", createRegion}, {"UnloadRegion", unloadRegion}, + + //triggers + {"SetOnLoad",setOnLoad}, + {"SetOnSave",setOnSave}, + {"SetOnCreate",setOnCreate}, + {"SetOnUnload",setOnUnload}, + + //sentinel {nullptr, nullptr} }; diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index 368f950..278bdb4 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -25,43 +25,71 @@ #include +//TODO: Could I push the pager to the API functions too? + Region* RegionPagerLua::LoadRegion(int x, int y) { - //load the region if possible + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, loadRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return nullptr; + } //something to work on Region tmpRegion(x, y); - - //API hook - lua_getglobal(lua, "Region"); - lua_getfield(lua, -1, "Load"); lua_pushlightuserdata(lua, &tmpRegion); + + //call the funtion, 1 arg, 1 return if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - //success or failure - if (!lua_toboolean(lua, -1)) { - lua_pop(lua, 2); + + //check the return value, success or failure + if (lua_toboolean(lua, -1)) { + lua_pop(lua, 1); + regionList.push_front(tmpRegion); + return ®ionList.front(); + } + else { + lua_pop(lua, 1); return nullptr; } - lua_pop(lua, 2); - regionList.push_front(tmpRegion); - return ®ionList.front(); } Region* RegionPagerLua::SaveRegion(int x, int y) { - //find & save the region - Region* ptr = FindRegion(x, y); - if (ptr) { - //API hook - lua_getglobal(lua, "Region"); - lua_getfield(lua, -1, "Save"); - lua_pushlightuserdata(lua, ptr); - if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); - } + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, saveRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { lua_pop(lua, 1); + return nullptr; + } + + //find the specified region + Region* ptr = FindRegion(x, y); + if (!ptr) { + lua_pop(lua, 1); + return nullptr; + } + lua_pushlightuserdata(lua, ptr); + + //call the function, 1 arg, 1 return + if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); + } + + //check the return value, success or failure + if (lua_toboolean(lua, -1)) { + lua_pop(lua, 1); + return ptr; + } + else { + lua_pop(lua, 1); + return nullptr; } - return ptr; } Region* RegionPagerLua::CreateRegion(int x, int y) { @@ -69,55 +97,87 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { throw(std::logic_error("Cannot overwrite an existing region")); } + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, createRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return nullptr; + } + //something to work on Region tmpRegion(x, y); - - //API hook - lua_getglobal(lua, "Region"); - lua_getfield(lua, -1, "Create"); lua_pushlightuserdata(lua, &tmpRegion); - //TODO: parameters + + //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(lua, 1); + + //return the new region regionList.push_front(tmpRegion); return ®ionList.front(); } void RegionPagerLua::UnloadRegion(int x, int y) { - lua_getglobal(lua, "Region"); + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef); + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return; + } + + //run each region through this lambda regionList.remove_if([&](Region& region) -> bool { if (region.GetX() == x && region.GetY() == y) { - //API hook - lua_getfield(lua, -1, "Unload"); + //push a copy of the function onto the stack with the region + lua_pushvalue(lua, -1); lua_pushlightuserdata(lua, ®ion); + + //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } + //signal to the container return true; } + //signal to the container return false; }); + //pop the base copy of the function lua_pop(lua, 1); } void RegionPagerLua::UnloadAll() { - lua_getglobal(lua, "Region"); + //get the pager's function from the registry + lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef); + + //check if this function is available + if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); + return; + } for (auto& it : regionList) { - //API hook - lua_getfield(lua, -1, "Unload"); + //push a copy of the function onto the stack with the region + lua_pushvalue(lua, -1); lua_pushlightuserdata(lua, &it); + + //call the function, 1 arg, 0 return if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } } + //pop the base copy of the function lua_pop(lua, 1); + + //remove from memory regionList.clear(); } \ No newline at end of file diff --git a/common/map/region_pager_lua.hpp b/common/map/region_pager_lua.hpp index 8543e2d..3835b9c 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -44,8 +44,25 @@ public: //accessors & mutators lua_State* SetLuaState(lua_State* L) { return lua = L; } lua_State* GetLuaState() { return lua; } + + //utilities for the API + int SetLoadReference(int i) { return loadRef = i; } + int SetSaveReference(int i) { return saveRef = i; } + int SetCreateReference(int i) { return createRef = i; } + int SetUnloadReference(int i) { return unloadRef = i; } + + int GetLoadReference() { return loadRef; } + int GetSaveReference() { return saveRef; } + int GetCreateReference() { return createRef; } + int GetUnloadReference() { return unloadRef; } + protected: lua_State* lua = nullptr; + + int loadRef = LUA_NOREF; + int saveRef = LUA_NOREF; + int createRef = LUA_NOREF; + int unloadRef = LUA_NOREF; }; #endif diff --git a/copyright.txt b/copyright.txt new file mode 100644 index 0000000..08613f0 --- /dev/null +++ b/copyright.txt @@ -0,0 +1,15 @@ +Future versions (to be determined) may be released under a modified version of the Uplink Developer's License. + +The current version of Tortuga is released under the zlib license. + +Copyright (c) 2013, 2014 Kayne Ruse + +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. \ No newline at end of file diff --git a/makefile b/makefile index 3a5a667..8ae66e9 100644 --- a/makefile +++ b/makefile @@ -19,7 +19,12 @@ debug: export CXXFLAGS+=-g debug: clean all release: export CXXFLAGS+=-static-libgcc -static-libstdc++ -release: clean all +release: clean all package + +#For use on my machine ONLY +package: + rar a -r -ep Tortuga.rar out/*.exe out/*.dll + rar a -r Tortuga.rar rsc/* copyright.txt $(OUTDIR): mkdir $(OUTDIR) diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index ce07f88..8b43720 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -15,10 +15,11 @@ tiles = { water = base + shift * 4 } ---could set custom generation systems here, that differ from the global generators, etc. -function Region.Create(region) - for i = 1, Region.GetWidth() do - for j = 1, Region.GetHeight() do +--custom generation systems here +function islandGenerator(region) + io.write("Generating (", Region.GetX(region), ", ", Region.GetY(region), ")\n") + for i = 1, Region.GetWidth(region) do + for j = 1, Region.GetHeight(region) do local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) if dist < 10 then Region.SetTile(region, i, j, 1, tiles.plains) @@ -33,14 +34,19 @@ function Region.Create(region) end --Get some regions ---BUG: The server fails without this -newRoom = RoomMgr.CreateRoom("overworld") +--BUG: The server fails without at least one room +--TODO: Create rooms with names? +newRoom = RoomManager.CreateRoom() pager = Room.GetPager(newRoom) +RegionPager.SetOnCreate(pager, islandGenerator) + +--[[ regionTable = { RegionPager.GetRegion(pager, Region.GetWidth() * 0, Region.GetHeight() * 0), RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() * 0), RegionPager.GetRegion(pager, Region.GetWidth() * 0, Region.GetHeight() *-1), RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() *-1) } +]] print("Finished the lua script") diff --git a/server/accounts/account_data.hpp b/server/accounts/account_data.hpp index 9c3d735..d7fb022 100644 --- a/server/accounts/account_data.hpp +++ b/server/accounts/account_data.hpp @@ -24,15 +24,35 @@ #include -struct AccountData { +class AccountData { +public: + AccountData() = default; + ~AccountData() = default; + + //accessors and mutators + int SetClientIndex(int i) { return clientIndex = i; } + int GetClientIndex() { return clientIndex; } + + std::string SetUsername(std::string s) { return username = s; } + std::string GetUsername() { return username; } + + //database stuff + bool GetBlackListed() { return blackListed; } + bool GetWhiteListed() { return whiteListed; } + bool GetModerator() { return mod; } + bool GetAdministrator() { return admin; } + +private: + friend class AccountManager; + + int clientIndex; std::string username; //TODO: password + bool blackListed = false; bool whiteListed = true; bool mod = false; bool admin = false; - - int clientIndex; }; #endif diff --git a/server/accounts/account_manager.hpp b/server/accounts/account_manager.hpp index 7c6cc1f..2e631b5 100644 --- a/server/accounts/account_manager.hpp +++ b/server/accounts/account_manager.hpp @@ -23,16 +23,14 @@ #define ACCOUNTMANAGER_HPP_ #include "account_data.hpp" +#include "singleton.hpp" #include "sqlite3/sqlite3.h" #include -class AccountManager { +class AccountManager : public Singleton { public: - AccountManager() = default; - ~AccountManager() { UnloadAll(); }; - //public access methods int CreateAccount(std::string username, int clientIndex); int LoadAccount(std::string username, int clientIndex); @@ -50,6 +48,11 @@ public: sqlite3* GetDatabase(); private: + friend Singleton; + + AccountManager() = default; + ~AccountManager() = default; + std::map accountMap; sqlite3* database = nullptr; }; diff --git a/server/accounts/makefile b/server/accounts/makefile index 8d12afe..f24e1ba 100644 --- a/server/accounts/makefile +++ b/server/accounts/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. +INCLUDES+=. ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/characters/character_data.hpp b/server/characters/character_data.hpp index 5650e36..edc3d01 100644 --- a/server/characters/character_data.hpp +++ b/server/characters/character_data.hpp @@ -31,27 +31,41 @@ #include #include -struct CharacterData { - //metadata - int owner; - std::string handle; - std::string avatar; +class CharacterData { +public: + CharacterData() = default; + ~CharacterData() = default; + + //location and movement + int SetRoomIndex(int i) { return roomIndex = i; } + Vector2 SetOrigin(Vector2 v) { return origin = v; } + Vector2 SetMotion(Vector2 v) { return motion = v; } + + int GetRoomIndex() { return roomIndex; } + Vector2 GetOrigin() { return origin; } + Vector2 GetMotion() { return motion; } + + //accessors and mutators + Statistics* GetBaseStats() { return &baseStats; } + + //database stuff + int GetOwner() { return owner; } + std::string GetHandle() { return handle; } + std::string GetAvatar() { return avatar; } + +private: + friend class CharacterManager; //world position int roomIndex = 0; Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; - //base statistics - Statistics stats; + Statistics baseStats; - //TODO: gameplay components: equipment, items, buffs, debuffs - - //active gameplay members - //NOTE: these are lost when unloaded - bool inCombat = false; - int atbGauge = 0; - //TODO: stored command + int owner; + std::string handle; + std::string avatar; }; #endif diff --git a/server/characters/character_manager.cpp b/server/characters/character_manager.cpp index bfc070c..baabac1 100644 --- a/server/characters/character_manager.cpp +++ b/server/characters/character_manager.cpp @@ -58,7 +58,7 @@ static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; //Define the methods //------------------------- -//NOTE: default stats as a parameter would be good for different beggining states or multiple classes +//NOTE: default baseStats as a parameter would be good for different beggining states or multiple classes int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) { //Create the character, failing if it exists sqlite3_stmt* statement = nullptr; @@ -142,20 +142,20 @@ int CharacterManager::LoadCharacter(int owner, std::string handle, std::string a newChar.origin.y = (double)sqlite3_column_int(statement, 7); //statistics - newChar.stats.level = sqlite3_column_int(statement, 8); - newChar.stats.exp = sqlite3_column_int(statement, 9); - newChar.stats.maxHP = sqlite3_column_int(statement, 10); - newChar.stats.health = sqlite3_column_int(statement, 11); - newChar.stats.maxMP = sqlite3_column_int(statement, 12); - newChar.stats.mana = sqlite3_column_int(statement, 13); - newChar.stats.attack = sqlite3_column_int(statement, 14); - newChar.stats.defence = sqlite3_column_int(statement, 15); - newChar.stats.intelligence = sqlite3_column_int(statement, 16); - newChar.stats.resistance = sqlite3_column_int(statement, 17); - newChar.stats.speed = sqlite3_column_int(statement, 18); - newChar.stats.accuracy = sqlite3_column_double(statement, 19); - newChar.stats.evasion = sqlite3_column_double(statement, 20); - newChar.stats.luck = sqlite3_column_double(statement, 21); + newChar.baseStats.level = sqlite3_column_int(statement, 8); + newChar.baseStats.exp = sqlite3_column_int(statement, 9); + newChar.baseStats.maxHP = sqlite3_column_int(statement, 10); + newChar.baseStats.health = sqlite3_column_int(statement, 11); + newChar.baseStats.maxMP = sqlite3_column_int(statement, 12); + newChar.baseStats.mana = sqlite3_column_int(statement, 13); + newChar.baseStats.attack = sqlite3_column_int(statement, 14); + newChar.baseStats.defence = sqlite3_column_int(statement, 15); + newChar.baseStats.intelligence = sqlite3_column_int(statement, 16); + newChar.baseStats.resistance = sqlite3_column_int(statement, 17); + newChar.baseStats.speed = sqlite3_column_int(statement, 18); + newChar.baseStats.accuracy = sqlite3_column_double(statement, 19); + newChar.baseStats.evasion = sqlite3_column_double(statement, 20); + newChar.baseStats.luck = sqlite3_column_double(statement, 21); //TODO: gameplay components: equipment, items, buffs, debuffs @@ -199,20 +199,20 @@ int CharacterManager::SaveCharacter(int uid) { ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK; //statistics - ret |= sqlite3_bind_int(statement, 5, character.stats.level) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 6, character.stats.exp) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 7, character.stats.maxHP) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 8, character.stats.health) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 9, character.stats.maxMP) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 10, character.stats.mana) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 11, character.stats.attack) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 12, character.stats.defence) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 13, character.stats.intelligence) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 14, character.stats.resistance) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 15, character.stats.speed) != SQLITE_OK; - ret |= sqlite3_bind_double(statement, 16, character.stats.accuracy) != SQLITE_OK; - ret |= sqlite3_bind_double(statement, 17, character.stats.evasion) != SQLITE_OK; - ret |= sqlite3_bind_double(statement, 18, character.stats.luck) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 5, character.baseStats.level) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 6, character.baseStats.exp) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 7, character.baseStats.maxHP) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 8, character.baseStats.health) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 9, character.baseStats.maxMP) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 10, character.baseStats.mana) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 11, character.baseStats.attack) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 12, character.baseStats.defence) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 13, character.baseStats.intelligence) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 14, character.baseStats.resistance) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 15, character.baseStats.speed) != SQLITE_OK; + ret |= sqlite3_bind_double(statement, 16, character.baseStats.accuracy) != SQLITE_OK; + ret |= sqlite3_bind_double(statement, 17, character.baseStats.evasion) != SQLITE_OK; + ret |= sqlite3_bind_double(statement, 18, character.baseStats.luck) != SQLITE_OK; //TODO: gameplay components: equipment, items, buffs, debuffs diff --git a/server/characters/character_manager.hpp b/server/characters/character_manager.hpp index 191fd4c..084d595 100644 --- a/server/characters/character_manager.hpp +++ b/server/characters/character_manager.hpp @@ -23,17 +23,15 @@ #define CHARACTERMANAGER_HPP_ #include "character_data.hpp" +#include "singleton.hpp" #include "sqlite3/sqlite3.h" #include #include -class CharacterManager { +class CharacterManager : public Singleton { public: - CharacterManager() = default; - ~CharacterManager() { UnloadAll(); }; - //public access methods int CreateCharacter(int owner, std::string handle, std::string avatar); int LoadCharacter(int owner, std::string handle, std::string avatar); @@ -53,6 +51,11 @@ public: sqlite3* GetDatabase(); private: + friend Singleton; + + CharacterManager() = default; + ~CharacterManager() = default; + std::map characterMap; sqlite3* database = nullptr; }; diff --git a/server/combat/combat_data.hpp b/server/combat/combat_data.hpp deleted file mode 100644 index 683e66f..0000000 --- a/server/combat/combat_data.hpp +++ /dev/null @@ -1,52 +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 COMBATDATA_HPP_ -#define COMBATDATA_HPP_ - -#include "vector2.hpp" -#include "combat_defines.hpp" - -//gameplay members -#include "character_data.hpp" -#include "enemy_data.hpp" - -//std namespace -#include -#include -#include - -struct CombatData { - typedef std::chrono::steady_clock Clock; - - std::array characterArray; - std::array enemyArray; - - //world interaction - int mapIndex = 0; - Vector2 origin = {0.0,0.0}; - Vector2 bounds = {0.0,0.0}; - - //time interval - Clock::time_point lastTick = Clock::now(); -}; - -#endif diff --git a/server/combat/combat_manager.cpp b/server/combat/combat_manager.cpp deleted file mode 100644 index be4f9ac..0000000 --- a/server/combat/combat_manager.cpp +++ /dev/null @@ -1,54 +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. -*/ -#include "combat_manager.hpp" - -//------------------------- -//public access methods -//------------------------- - -//TODO - -//------------------------- -//accessors and mutators -//------------------------- - -CombatData* CombatManager::GetCombat(int uid) { - std::map::iterator it = combatMap.find(uid); - - if (it == combatMap.end()) { - return nullptr; - } - - return &it->second; -} - -std::map* CombatManager::GetContainer() { - return &combatMap; -} - -lua_State* CombatManager::SetLuaState(lua_State* L) { - return luaState = L; -} - -lua_State* CombatManager::GetLuaState() { - return luaState; -} diff --git a/server/combat/combat_manager.hpp b/server/combat/combat_manager.hpp deleted file mode 100644 index 77573ab..0000000 --- a/server/combat/combat_manager.hpp +++ /dev/null @@ -1,51 +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 COMBATMANAGER_HPP_ -#define COMBATMANAGER_HPP_ - -#include "combat_data.hpp" - -#include "lua/lua.hpp" - -#include - -class CombatManager { -public: - CombatManager() = default; - ~CombatManager() = default; - - //public access methods - //TODO - - //accessors and mutators - CombatData* GetCombat(int uid); - std::map* GetContainer(); - - lua_State* SetLuaState(lua_State*); - lua_State* GetLuaState(); - -private: - std::map combatMap; - lua_State* luaState = nullptr; -}; - -#endif \ No newline at end of file diff --git a/server/combat/makefile b/server/combat/makefile deleted file mode 100644 index 4d71462..0000000 --- a/server/combat/makefile +++ /dev/null @@ -1,37 +0,0 @@ -#config -INCLUDES+=. ../../common/gameplay ../../common/utilities ../characters ../enemies -LIBS+= -CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) - -#source -CXXSRC=$(wildcard *.cpp) - -#objects -OBJDIR=obj -OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) - -#output -OUTDIR=.. -OUT=$(addprefix $(OUTDIR)/,server.a) - -#targets -all: $(OBJ) $(OUT) - ar -crs $(OUT) $(OBJ) - -$(OBJ): | $(OBJDIR) - -$(OUT): | $(OUTDIR) - -$(OBJDIR): - mkdir $(OBJDIR) - -$(OUTDIR): - mkdir $(OUTDIR) - -$(OBJDIR)/%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - $(RM) *.o *.a *.exe - -rebuild: clean all diff --git a/server/enemies/enemy_data.hpp b/server/enemies/enemy_data.hpp deleted file mode 100644 index ab1ef89..0000000 --- a/server/enemies/enemy_data.hpp +++ /dev/null @@ -1,47 +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 ENEMYDATA_HPP_ -#define ENEMYDATA_HPP_ - -#include "vector2.hpp" -#include "statistics.hpp" - -//std namespace -#include - -struct EnemyData { - //metadata - std::string handle; - std::string avatar; - - //gameplay - Statistics stats; - - //TODO: gameplay components: equipment, items, buffs, debuffs, rewards - - //active gameplay members - //NOTE: these are lost when unloaded - int tableIndex; - int atbGauge = 0; -}; - -#endif diff --git a/server/enemies/enemy_manager.cpp b/server/enemies/enemy_manager.cpp deleted file mode 100644 index 2b49d3d..0000000 --- a/server/enemies/enemy_manager.cpp +++ /dev/null @@ -1,54 +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. -*/ -#include "enemy_manager.hpp" - -//------------------------- -//public access methods -//------------------------- - -//TODO - -//------------------------- -//accessors and mutators -//------------------------- - -EnemyData* EnemyManager::GetEnemy(int uid) { - std::map::iterator it = enemyMap.find(uid); - - if (it == enemyMap.end()) { - return nullptr; - } - - return &it->second; -} - -std::map* EnemyManager::GetContainer() { - return &enemyMap; -} - -lua_State* EnemyManager::SetLuaState(lua_State* L) { - return luaState = L; -} - -lua_State* EnemyManager::GetLuaState() { - return luaState; -} diff --git a/server/enemies/enemy_manager.hpp b/server/enemies/enemy_manager.hpp deleted file mode 100644 index dae86ad..0000000 --- a/server/enemies/enemy_manager.hpp +++ /dev/null @@ -1,51 +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 ENEMYMANAGER_HPP_ -#define ENEMYMANAGER_HPP_ - -#include "enemy_data.hpp" - -#include "lua/lua.hpp" - -#include - -class EnemyManager { -public: - EnemyManager() = default; - ~EnemyManager() = default; - - //public access methods - //TODO - - //accessors and mutators - EnemyData* GetEnemy(int uid); - std::map* GetContainer(); - - lua_State* SetLuaState(lua_State*); - lua_State* GetLuaState(); - -private: - std::map enemyMap; - lua_State* luaState = nullptr; -}; - -#endif \ No newline at end of file diff --git a/server/enemies/makefile b/server/enemies/makefile deleted file mode 100644 index 8c2156a..0000000 --- a/server/enemies/makefile +++ /dev/null @@ -1,37 +0,0 @@ -#config -INCLUDES+=. ../mapgen ../../common/gameplay ../../common/map ../../common/utilities -LIBS+= -CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) - -#source -CXXSRC=$(wildcard *.cpp) - -#objects -OBJDIR=obj -OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) - -#output -OUTDIR=.. -OUT=$(addprefix $(OUTDIR)/,server.a) - -#targets -all: $(OBJ) $(OUT) - ar -crs $(OUT) $(OBJ) - -$(OBJ): | $(OBJDIR) - -$(OUT): | $(OUTDIR) - -$(OBJDIR): - mkdir $(OBJDIR) - -$(OUTDIR): - mkdir $(OUTDIR) - -$(OBJDIR)/%.o: %.cpp - $(CXX) $(CXXFLAGS) -c -o $@ $< - -clean: - $(RM) *.o *.a *.exe - -rebuild: clean all diff --git a/server/linit.cpp b/server/linit.cpp index 072120f..052f967 100644 --- a/server/linit.cpp +++ b/server/linit.cpp @@ -40,7 +40,7 @@ #include "region_pager_api.hpp" #include "tile_sheet_api.hpp" #include "room_api.hpp" -#include "room_mgr_api.hpp" +#include "room_manager_api.hpp" //these libs are loaded by lua.c and are readily available to any Lua program static const luaL_Reg loadedlibs[] = { @@ -61,7 +61,7 @@ static const luaL_Reg loadedlibs[] = { {TORTUGA_REGION_PAGER_NAME, openRegionPagerAPI}, {TORTUGA_TILE_SHEET_NAME, openTileSheetAPI}, {TORTUGA_ROOM_NAME, openRoomAPI}, - {TORTUGA_ROOM_MGR_NAME, openRoomMgrAPI}, + {TORTUGA_ROOM_MANAGER_NAME, openRoomManagerAPI}, {NULL, NULL} }; diff --git a/server/main.cpp b/server/main.cpp index 71ebb7c..8987d26 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -33,7 +33,10 @@ using namespace std; int main(int argc, char** argv) { try { //create the singletons + AccountManager::Create(); + CharacterManager::Create(); ConfigUtility::Create(); + RoomManager::Create(); UDPNetworkUtility::Create(); //call the server's routines @@ -47,7 +50,10 @@ int main(int argc, char** argv) { ServerApplication::Delete(); //delete the singletons + AccountManager::Delete(); + CharacterManager::Delete(); ConfigUtility::Delete(); + RoomManager::Delete(); UDPNetworkUtility::Delete(); } catch(exception& e) { diff --git a/server/makefile b/server/makefile index 807cd13..b096f70 100644 --- a/server/makefile +++ b/server/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities +INCLUDES+=. accounts characters rooms ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities LIBS+=server.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) @@ -18,8 +18,6 @@ OUT=$(addprefix $(OUTDIR)/,server) all: $(OBJ) $(OUT) $(MAKE) -C accounts $(MAKE) -C characters - $(MAKE) -C combat - $(MAKE) -C enemies $(MAKE) -C rooms $(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS) diff --git a/server/rooms/makefile b/server/rooms/makefile index f4921ea..ea66828 100644 --- a/server/rooms/makefile +++ b/server/rooms/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../mapgen ../mapgen/generators ../../common/map +INCLUDES+=. ../../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 2f1d103..636d206 100644 --- a/server/rooms/room_api.cpp +++ b/server/rooms/room_api.cpp @@ -25,26 +25,25 @@ static int getPager(lua_State* L) { RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); - lua_pushlightuserdata(L, reinterpret_cast(&room->pager)); + lua_pushlightuserdata(L, reinterpret_cast(room->GetPager()) ); return 1; } -static int onCreate(lua_State* L) { - //TODO: onCreate() +static int create(lua_State* L) { + //EMPTY + //NOTE: This can be used to set defaults for the pager return 0; } -static int onUnload(lua_State* L) { - //TODO: onUnload() +static int unload(lua_State* L) { + //EMPTY return 0; } -//TODO: parameters - static const luaL_Reg roomLib[] = { {"GetPager",getPager}, - {"OnCreate", onCreate}, - {"OnUnload", onUnload}, + {"Create", create}, + {"Unload", unload}, {nullptr, nullptr} }; diff --git a/server/rooms/room_data.hpp b/server/rooms/room_data.hpp index 4f1b669..539a56e 100644 --- a/server/rooms/room_data.hpp +++ b/server/rooms/room_data.hpp @@ -25,12 +25,19 @@ //map system #include "region_pager_lua.hpp" -struct RoomData { +class RoomData { +public: + RoomData() = default; + ~RoomData() = default; + + //accessors and mutators + RegionPagerLua* GetPager() { return &pager; } + +private: + friend class RoomManager; + //members RegionPagerLua pager; - - //TODO: collision map - //TODO: NPCs? }; #endif diff --git a/server/rooms/room_manager.cpp b/server/rooms/room_manager.cpp index 5560050..4560fe9 100644 --- a/server/rooms/room_manager.cpp +++ b/server/rooms/room_manager.cpp @@ -21,27 +21,25 @@ */ #include "room_manager.hpp" +#include "room_api.hpp" + #include //------------------------- //public access methods //------------------------- -RoomData* RoomManager::CreateRoom() { +int RoomManager::CreateRoom() { //create the room RoomData* newRoom = new RoomData(); - - //set the state - if (luaState) { - newRoom->pager.SetLuaState(luaState); - } + newRoom->pager.SetLuaState(luaState); //register the room - roomMap[counter++] = newRoom; + roomMap[counter] = newRoom; //API hook - lua_getglobal(luaState, "Room"); - lua_getfield(luaState, -1, "OnCreate"); + 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) )); @@ -49,7 +47,7 @@ RoomData* RoomManager::CreateRoom() { lua_pop(luaState, 1); //finish the routine - return newRoom; + return counter++; } void RoomManager::UnloadRoom(int uid) { @@ -60,8 +58,8 @@ void RoomManager::UnloadRoom(int uid) { } //API hook - lua_getglobal(luaState, "Room"); - lua_getfield(luaState, -1, "OnUnload"); + 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) )); @@ -92,11 +90,11 @@ int RoomManager::PushRoom(RoomData* room) { } void RoomManager::UnloadAll() { - lua_getglobal(luaState, "Room"); + lua_getglobal(luaState, TORTUGA_ROOM_NAME); for (auto& it : roomMap) { //API hook - lua_getfield(luaState, -1, "OnUnload"); + 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) )); diff --git a/server/rooms/room_manager.hpp b/server/rooms/room_manager.hpp index 71c2bbf..2f13893 100644 --- a/server/rooms/room_manager.hpp +++ b/server/rooms/room_manager.hpp @@ -23,20 +23,16 @@ #define ROOMMANAGER_HPP_ #include "room_data.hpp" +#include "singleton.hpp" #include "lua/lua.hpp" #include -#define ROOM_MANAGER_PSEUDOINDEX "RoomManager" - -class RoomManager { +class RoomManager : public Singleton { public: - RoomManager() = default; - ~RoomManager() = default; - //public access methods - RoomData* CreateRoom(); + int CreateRoom(); void UnloadRoom(int uid); RoomData* GetRoom(int uid); @@ -52,6 +48,11 @@ public: lua_State* GetLuaState() { return luaState; } private: + friend Singleton; + + RoomManager() = default; + ~RoomManager() = default; + std::map roomMap; lua_State* luaState = nullptr; int counter = 0; diff --git a/server/rooms/room_mgr_api.cpp b/server/rooms/room_manager_api.cpp similarity index 55% rename from server/rooms/room_mgr_api.cpp rename to server/rooms/room_manager_api.cpp index 3c96f4e..02565b9 100644 --- a/server/rooms/room_mgr_api.cpp +++ b/server/rooms/room_manager_api.cpp @@ -19,61 +19,42 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "room_mgr_api.hpp" +#include "room_manager_api.hpp" -#include "room_api.hpp" #include "room_manager.hpp" -#include "room_data.hpp" #include static int getRoom(lua_State* L) { - //get the room manager - lua_pushstring(L, ROOM_MANAGER_PSEUDOINDEX); - lua_gettable(L, LUA_REGISTRYINDEX); - RoomManager* roomMgr = reinterpret_cast(lua_touserdata(L, -1)); - - //push the room and return it - lua_pushlightuserdata(L, reinterpret_cast( roomMgr->GetRoom(lua_tointeger(L, -2)) )); + //find, push and return the room + RoomData* room = RoomManager::GetSingleton().GetRoom(lua_tointeger(L, -2)); + lua_pushlightuserdata(L, reinterpret_cast(room)); return 1; } static int createRoom(lua_State* L) { //TODO: check parameter count for the glue functions - //get the room manager - lua_pushstring(L, ROOM_MANAGER_PSEUDOINDEX); - lua_gettable(L, LUA_REGISTRYINDEX); - RoomManager* roomMgr = reinterpret_cast(lua_touserdata(L, -1)); - - //create the room - RoomData* newRoom = roomMgr->CreateRoom(); - - //return the new room - lua_pushlightuserdata(L, newRoom); + //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) { - //get the room manager - lua_pushstring(L, ROOM_MANAGER_PSEUDOINDEX); - lua_gettable(L, LUA_REGISTRYINDEX); - RoomManager* roomMgr = reinterpret_cast(lua_touserdata(L, -1)); - //unload the specified room - roomMgr->UnloadRoom(lua_tointeger(L, -2)); - + RoomManager::GetSingleton().UnloadRoom(lua_tointeger(L, -2)); return 0; } -static const luaL_Reg roomMgrLib[] = { +static const luaL_Reg roomManagerLib[] = { {"GetRoom",getRoom}, {"CreateRoom",createRoom}, {"UnloadRoom",unloadRoom}, {nullptr, nullptr} }; -LUAMOD_API int openRoomMgrAPI(lua_State* L) { - luaL_newlib(L, roomMgrLib); +LUAMOD_API int openRoomManagerAPI(lua_State* L) { + luaL_newlib(L, roomManagerLib); return 1; } \ No newline at end of file diff --git a/server/rooms/room_mgr_api.hpp b/server/rooms/room_manager_api.hpp similarity index 85% rename from server/rooms/room_mgr_api.hpp rename to server/rooms/room_manager_api.hpp index f870e5e..529f5bd 100644 --- a/server/rooms/room_mgr_api.hpp +++ b/server/rooms/room_manager_api.hpp @@ -19,12 +19,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef ROOMMGRAPI_HPP_ -#define ROOMMGRAPI_HPP_ +#ifndef ROOMMANAGERAPI_HPP_ +#define ROOMMANAGERAPI_HPP_ #include "lua/lua.hpp" -#define TORTUGA_ROOM_MGR_NAME "RoomMgr" -LUAMOD_API int openRoomMgrAPI(lua_State* L); +#define TORTUGA_ROOM_MANAGER_NAME "RoomManager" +LUAMOD_API int openRoomManagerAPI(lua_State* L); #endif diff --git a/server/server_application.hpp b/server/server_application.hpp index 17b6e41..372549b 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -92,13 +92,13 @@ private: std::map clientMap; //managers - AccountManager accountMgr; - CharacterManager characterMgr; - RoomManager roomMgr; + AccountManager& accountMgr = AccountManager::GetSingleton(); + CharacterManager& characterMgr = CharacterManager::GetSingleton(); + RoomManager& roomMgr = RoomManager::GetSingleton(); //misc bool running = true; - int clientUID = 0; + int clientIndex = 0; }; #endif diff --git a/server/server_logic.cpp b/server/server_logic.cpp new file mode 100644 index 0000000..e4e1f5f --- /dev/null +++ b/server/server_logic.cpp @@ -0,0 +1,233 @@ +/* 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" + +//for PACKET_BUFFER_SIZE +#include "serial.hpp" + +//utility functions +#include "sql_utility.hpp" +#include "utility.hpp" + +#include +#include +#include + +//------------------------- +//public methods +//------------------------- + +void ServerApplication::Init(int argc, char** argv) { + //NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed. + std::cout << "Beginning " << argv[0] << std::endl; + + //load the prerequisites + config.Load("rsc\\config.cfg"); + + //------------------------- + //Initialize the APIs + //------------------------- + + //Init SDL + if (SDL_Init(0)) { + throw(std::runtime_error("Failed to initialize SDL")); + } + std::cout << "Initialized SDL" << std::endl; + + //Init SDL_net + if (SDLNet_Init()) { + throw(std::runtime_error("Failed to initialize SDL_net")); + } + network.Open(config.Int("server.port")); + std::cout << "Initialized SDL_net" << std::endl; + + //Init SQL + int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr); + if (ret != SQLITE_OK || !database) { + throw(std::runtime_error(std::string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) )); + } + std::cout << "Initialized SQL" << std::endl; + + //Init lua + luaState = luaL_newstate(); + if (!luaState) { + throw(std::runtime_error("Failed to initialize lua")); + } + luaL_openlibs(luaState); + std::cout << "Initialized lua" << std::endl; + + //------------------------- + //Setup the objects + //------------------------- + + //set the hooks + accountMgr.SetDatabase(database); + characterMgr.SetDatabase(database); + + roomMgr.SetLuaState(luaState); + + std::cout << "Internal managers initialized" << std::endl; + + //------------------------- + //Run the startup scripts + //------------------------- + + //setup the database + if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) { + throw(std::runtime_error("Failed to initialize SQL's setup script")); + } + std::cout << "Completed SQL's setup script" << std::endl; + + //run lua's startup script + if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) { + throw(std::runtime_error(std::string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) )); + } + std::cout << "Completed lua's setup script" << std::endl; + + //------------------------- + //debug output + //------------------------- + + //TODO: enable/disable these with a switch +#define DEBUG_OUTPUT_VAR(x) std::cout << "\t" << #x << ": " << x << std::endl; + + std::cout << "Internal sizes:" << std::endl; + + DEBUG_OUTPUT_VAR(sizeof(Region::type_t)); + DEBUG_OUTPUT_VAR(sizeof(Region)); + DEBUG_OUTPUT_VAR(REGION_WIDTH); + DEBUG_OUTPUT_VAR(REGION_HEIGHT); + DEBUG_OUTPUT_VAR(REGION_DEPTH); + DEBUG_OUTPUT_VAR(REGION_SOLID_FOOTPRINT); + DEBUG_OUTPUT_VAR(REGION_FOOTPRINT); + DEBUG_OUTPUT_VAR(PACKET_BUFFER_SIZE); + DEBUG_OUTPUT_VAR(MAX_PACKET_SIZE); + +#undef DEBUG_OUTPUT_VAR + + //------------------------- + //finalize the startup + //------------------------- + + std::cout << "Startup completed successfully" << std::endl; + + //------------------------- + //debugging + //------------------------- + + //... +} + +void ServerApplication::Proc() { + SerialPacket* packetBuffer = reinterpret_cast(new char[MAX_PACKET_SIZE]); + while(running) { + //suck in the waiting packets & process them + while(network.Receive(packetBuffer)) { + HandlePacket(packetBuffer); + } + //update the internals + //BUG: #30 Update the internals i.e. player positions + + //give the computer a break + SDL_Delay(10); + } + delete reinterpret_cast(packetBuffer); +} + +void ServerApplication::Quit() { + std::cout << "Shutting down" << std::endl; + + //close the managers + clientMap.clear(); + accountMgr.UnloadAll(); + characterMgr.UnloadAll(); + //TODO: unload combats + //TODO: unload enemies + roomMgr.UnloadAll(); + + //APIs + lua_close(luaState); + sqlite3_close_v2(database); + network.Close(); + SDLNet_Quit(); + SDL_Quit(); + + std::cout << "Clean exit" << std::endl; +} + +//------------------------- +//direct incoming traffic +//------------------------- + +void ServerApplication::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { + //basic connections + case SerialPacketType::BROADCAST_REQUEST: + HandleBroadcastRequest(static_cast(argPacket)); + break; + case SerialPacketType::JOIN_REQUEST: + HandleJoinRequest(static_cast(argPacket)); + break; + case SerialPacketType::DISCONNECT: + HandleDisconnect(static_cast(argPacket)); + break; + case SerialPacketType::SHUTDOWN: + HandleShutdown(static_cast(argPacket)); + break; + + //map management + case SerialPacketType::REGION_REQUEST: + HandleRegionRequest(static_cast(argPacket)); + break; + + //combat management + //TODO: combat management + + //character management + case SerialPacketType::CHARACTER_NEW: + HandleCharacterNew(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_DELETE: + HandleCharacterDelete(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_UPDATE: + case SerialPacketType::CHARACTER_STATS_REQUEST: + HandleCharacterUpdate(static_cast(argPacket)); + break; + + //enemy management + //TODO: enemy management + + //mismanagement + case SerialPacketType::SYNCHRONIZE: + HandleSynchronize(static_cast(argPacket)); + break; + + //handle errors + default: { + std::string msg = "Unknown SerialPacketType encountered in the server: "; + msg += to_string_custom(static_cast(argPacket->type)); + throw(std::runtime_error(msg)); + } + break; + } +} \ No newline at end of file diff --git a/server/server_application.cpp b/server/server_methods.cpp similarity index 54% rename from server/server_application.cpp rename to server/server_methods.cpp index 99179c4..d993b83 100644 --- a/server/server_application.cpp +++ b/server/server_methods.cpp @@ -21,220 +21,7 @@ */ #include "server_application.hpp" -//for PACKET_BUFFER_SIZE -#include "serial.hpp" - -//utility functions -#include "sql_utility.hpp" -#include "utility.hpp" - -#include #include -#include - -//------------------------- -//public methods -//------------------------- - -void ServerApplication::Init(int argc, char** argv) { - //NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed. - std::cout << "Beginning " << argv[0] << std::endl; - - //load the prerequisites - config.Load("rsc\\config.cfg"); - - //------------------------- - //Initialize the APIs - //------------------------- - - //Init SDL - if (SDL_Init(0)) { - throw(std::runtime_error("Failed to initialize SDL")); - } - std::cout << "Initialized SDL" << std::endl; - - //Init SDL_net - if (SDLNet_Init()) { - throw(std::runtime_error("Failed to initialize SDL_net")); - } - network.Open(config.Int("server.port")); - std::cout << "Initialized SDL_net" << std::endl; - - //Init SQL - int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr); - if (ret != SQLITE_OK || !database) { - throw(std::runtime_error(std::string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) )); - } - std::cout << "Initialized SQL" << std::endl; - - //Init lua - luaState = luaL_newstate(); - if (!luaState) { - throw(std::runtime_error("Failed to initialize lua")); - } - luaL_openlibs(luaState); - std::cout << "Initialized lua" << std::endl; - - //------------------------- - //Setup the objects - //------------------------- - - //set the hooks - accountMgr.SetDatabase(database); - characterMgr.SetDatabase(database); - - roomMgr.SetLuaState(luaState); - - std::cout << "Internal managers set" << std::endl; - - //register the "globals" - lua_pushstring(luaState, ROOM_MANAGER_PSEUDOINDEX); - lua_pushlightuserdata(luaState, &roomMgr); - lua_settable(luaState, LUA_REGISTRYINDEX); - - std::cout << "Internal managers registered with lua" << std::endl; - - //------------------------- - //Run the startup scripts - //------------------------- - - //setup the database - if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) { - throw(std::runtime_error("Failed to initialize SQL's setup script")); - } - std::cout << "Completed SQL's setup script" << std::endl; - - //run lua's startup script - if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) { - throw(std::runtime_error(std::string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) )); - } - std::cout << "Completed lua's setup script" << std::endl; - - //------------------------- - //debug output - //------------------------- - - //TODO: enable/disable these with a switch -#define DEBUG_OUTPUT_VAR(x) std::cout << "\t" << #x << ": " << x << std::endl; - - std::cout << "Internal sizes:" << std::endl; - - DEBUG_OUTPUT_VAR(sizeof(Region::type_t)); - DEBUG_OUTPUT_VAR(sizeof(Region)); - DEBUG_OUTPUT_VAR(REGION_WIDTH); - DEBUG_OUTPUT_VAR(REGION_HEIGHT); - DEBUG_OUTPUT_VAR(REGION_DEPTH); - DEBUG_OUTPUT_VAR(REGION_SOLID_FOOTPRINT); - DEBUG_OUTPUT_VAR(REGION_FOOTPRINT); - DEBUG_OUTPUT_VAR(PACKET_BUFFER_SIZE); - DEBUG_OUTPUT_VAR(MAX_PACKET_SIZE); - -#undef DEBUG_OUTPUT_VAR - - //------------------------- - //finalize the startup - //------------------------- - - std::cout << "Startup completed successfully" << std::endl; - - //------------------------- - //debugging - //------------------------- - - //... -} - -void ServerApplication::Proc() { - SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); - while(running) { - //suck in the waiting packets & process them - while(network.Receive(packetBuffer)) { - HandlePacket(packetBuffer); - } - //update the internals - //BUG: #30 Update the internals i.e. player positions - - //give the computer a break - SDL_Delay(10); - } - free(static_cast(packetBuffer)); -} - -void ServerApplication::Quit() { - std::cout << "Shutting down" << std::endl; - - //close the managers - clientMap.clear(); - accountMgr.UnloadAll(); - characterMgr.UnloadAll(); - //TODO: unload combats - //TODO: unload enemies - roomMgr.UnloadAll(); - - //APIs - lua_close(luaState); - sqlite3_close_v2(database); - network.Close(); - SDLNet_Quit(); - SDL_Quit(); - - std::cout << "Clean exit" << std::endl; -} - -//------------------------- -//handle incoming traffic -//------------------------- - -void ServerApplication::HandlePacket(SerialPacket* const argPacket) { - switch(argPacket->type) { - //basic connections - case SerialPacketType::BROADCAST_REQUEST: - HandleBroadcastRequest(static_cast(argPacket)); - break; - case SerialPacketType::JOIN_REQUEST: - HandleJoinRequest(static_cast(argPacket)); - break; - case SerialPacketType::DISCONNECT: - HandleDisconnect(static_cast(argPacket)); - break; - case SerialPacketType::SHUTDOWN: - HandleShutdown(static_cast(argPacket)); - break; - - //map management - case SerialPacketType::REGION_REQUEST: - HandleRegionRequest(static_cast(argPacket)); - break; - - //combat management - //TODO: combat management - - //character management - case SerialPacketType::CHARACTER_NEW: - HandleCharacterNew(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_UPDATE: - case SerialPacketType::CHARACTER_STATS_REQUEST: - HandleCharacterUpdate(static_cast(argPacket)); - break; - - //enemy management - //TODO: enemy management - - //mismanagement - case SerialPacketType::SYNCHRONIZE: - HandleSynchronize(static_cast(argPacket)); - break; - - //handle errors - default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(static_cast(argPacket->type)) )); - break; - } -} //------------------------- //basic connections @@ -259,7 +46,7 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { //load the user account //TODO: handle passwords - int accountIndex = accountMgr.LoadAccount(argPacket->username, clientUID); + int accountIndex = accountMgr.LoadAccount(argPacket->username, clientIndex); if (accountIndex < 0) { //TODO: send rejection packet std::cerr << "Error: Account already loaded: " << accountIndex << std::endl; @@ -269,13 +56,13 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { //send the client their info ClientPacket newPacket; newPacket.type = SerialPacketType::JOIN_RESPONSE; - newPacket.clientIndex = clientUID; + newPacket.clientIndex = clientIndex; newPacket.accountIndex = accountIndex; network.SendTo(&newClient.address, static_cast(&newPacket)); //finished this routine - clientMap[clientUID++] = newClient; + clientMap[clientIndex++] = newClient; std::cout << "New connection, " << clientMap.size() << " clients and " << accountMgr.GetContainer()->size() << " accounts total" << std::endl; } @@ -291,17 +78,16 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { if neither of the above is true, then output a warning to the console, and return */ - //forward to the specified client network.SendTo( - &clientMap[ accountMgr.GetAccount(argPacket->accountIndex)->clientIndex ].address, + &clientMap[ accountMgr.GetAccount(argPacket->accountIndex)->GetClientIndex() ].address, static_cast(argPacket) ); //save and unload this account's characters //pump the unload message to all remaining clients characterMgr.UnloadCharacterIf([&](std::map::iterator it) -> bool { - if (argPacket->accountIndex == it->second.owner) { + if (argPacket->accountIndex == it->second.GetOwner()) { PumpCharacterUnload(it->first); return true; } @@ -309,7 +95,7 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { }); //erase the in-memory stuff - clientMap.erase(accountMgr.GetAccount(argPacket->accountIndex)->clientIndex); + clientMap.erase(accountMgr.GetAccount(argPacket->accountIndex)->GetClientIndex()); accountMgr.UnloadAccount(argPacket->accountIndex); //finished this routine @@ -349,7 +135,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { newPacket.x = argPacket->x; newPacket.y = argPacket->y; - newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->pager.GetRegion(argPacket->x, argPacket->y); + newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y); //send the content network.SendTo(&argPacket->srcAddress, static_cast(&newPacket)); @@ -422,11 +208,11 @@ void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) } //accept client-side logic - character->roomIndex = argPacket->roomIndex; - character->origin = argPacket->origin; - character->motion = argPacket->motion; + character->SetRoomIndex(argPacket->roomIndex); + character->SetOrigin(argPacket->origin); + character->SetMotion(argPacket->motion); - character->stats = argPacket->stats; + *character->GetBaseStats() = argPacket->stats; //TODO: gameplay components: equipment, items, buffs, debuffs @@ -485,11 +271,11 @@ void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int //TODO: keep this up to date when the character changes packet->characterIndex = characterIndex; - strncpy(packet->handle, character->handle.c_str(), PACKET_STRING_SIZE); - strncpy(packet->avatar, character->avatar.c_str(), PACKET_STRING_SIZE); - packet->accountIndex = character->owner; - packet->roomIndex = character->roomIndex; - packet->origin = character->origin; - packet->motion = character->motion; - packet->stats = character->stats; + strncpy(packet->handle, character->GetHandle().c_str(), PACKET_STRING_SIZE); + strncpy(packet->avatar, character->GetAvatar().c_str(), PACKET_STRING_SIZE); + packet->accountIndex = character->GetOwner(); + packet->roomIndex = character->GetRoomIndex(); + packet->origin = character->GetOrigin(); + packet->motion = character->GetMotion(); + packet->stats = *character->GetBaseStats(); } \ No newline at end of file diff --git a/todo.txt b/todo.txt index a1f8458..284be85 100644 --- a/todo.txt +++ b/todo.txt @@ -1,41 +1,14 @@ TODO: encapsulate the data structures -TODO: Get the rooms working TODO: A proper logging system +TODO: Ping-pong and keep alive system +TODO: Move the statistics into their own SQL table, instead of duplicating the structure a dozen times +TODO: Get the rooms working, even if only via hotkeys +TODO: Rejection messages +TODO: Fix shoddy movement TODO: make the whole thing more fault tolerant TODO: Authentication TODO: server is slaved to the client TODO: Time delay for requesting region packets TODO: command line parameters overriding config.cfg settings - ---Requirements-- - -The enemies need AI scripts -The scripts need to be able to generate other enemies (frog king). -The characters need a flag to show if they're in a combat instance or not, to signify of they should be unloaded client-side -On each game loop, the server should envoke each combat instance's update function - Each combat instance invokes each enemy's and character's update functions - These update functions increase the ATB guagues - if an ATB guage is full - than the stored command is executed - the players issue their commands during the build up - if there isn't a command ready, then the player is still choosing - for the enemies, the stored commands are driven by scripts, so when the enemies need to attack, their attached scripts are called. - after the commands are called, the ATB is reset to 0. - etc... - ---Enemy API-- - -enemyTables -- The global store of enemy tables. Only accessed by C++ code (unless you want to break something). - -enemy.new(parameters) -- return a new enemy object - -table.logic: the AI logic. If null, do nothing -table.ref: reference to the enemy itself, for use by API functions, set by constructor? - -combat -- the combat API -combat.new(mapIndex, x, y) -- return combat instance's index -combat.pushenemy(c, enemy) -- return the enemy's position -combat.popenemy(c, position) -- -