diff --git a/client/client_application.cpp b/client/client_application.cpp index caf465d..cbb670d 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -169,6 +169,7 @@ void ClientApplication::Quit() { //------------------------- void ClientApplication::LoadScene(SceneList sceneIndex) { + //BUG: #16 Resources are being reloaded between scenes UnloadScene(); switch(sceneIndex) { //add scene creation calls here diff --git a/client/gameplay_scenes/world.hpp b/client/gameplay_scenes/world.hpp index bb57f75..a2af0a2 100644 --- a/client/gameplay_scenes/world.hpp +++ b/client/gameplay_scenes/world.hpp @@ -96,6 +96,7 @@ protected: void UpdateMap(); //character management + void hCharacterUpdate(CharacterPacket* const); void hCharacterCreate(CharacterPacket* const); void hCharacterDelete(CharacterPacket* const); void hQueryCharacterExists(CharacterPacket* const); diff --git a/client/gameplay_scenes/world_characters.cpp b/client/gameplay_scenes/world_characters.cpp index 4091824..85a4dc2 100644 --- a/client/gameplay_scenes/world_characters.cpp +++ b/client/gameplay_scenes/world_characters.cpp @@ -35,6 +35,24 @@ //DOCS: new characters will result in create messages //DOCS: this client's character will exist in both (skipped) +void World::hCharacterUpdate(CharacterPacket* const argPacket) { + //TODO: (1) Authentication + //NOTE: applies to the local character too + + //check that this character exists + std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); + if (characterIt != characterMap.end()) { + //update the origin and motion, if there's a difference + if (characterIt->second.GetOrigin() != argPacket->origin) { + characterIt->second.SetOrigin(argPacket->origin); + } + if (characterIt->second.GetMotion() != argPacket->motion) { + characterIt->second.SetMotion(argPacket->motion); + characterIt->second.CorrectSprite(); //only correct the sprite if the motion changes + } + } +} + void World::hCharacterCreate(CharacterPacket* const argPacket) { //prevent double message if (characterMap.find(argPacket->characterIndex) != characterMap.end()) { diff --git a/client/gameplay_scenes/world_logic.cpp b/client/gameplay_scenes/world_logic.cpp index dcb74d0..b766140 100644 --- a/client/gameplay_scenes/world_logic.cpp +++ b/client/gameplay_scenes/world_logic.cpp @@ -173,7 +173,7 @@ void World::Render(SDL_Surface* const screen) { //draw the entities for (auto& it : characterMap) { - //TODO: (1) depth ordering + //BUG: #29 Characters (and other entities) are drawn out of order it.second.DrawTo(screen, camera.x, camera.y); } for (auto& it : monsterMap) { @@ -335,6 +335,9 @@ void World::HandlePacket(SerialPacket* const argPacket) { break; //character management + case SerialPacketType::CHARACTER_UPDATE: + hCharacterUpdate(static_cast(argPacket)); + break; case SerialPacketType::CHARACTER_CREATE: hCharacterCreate(static_cast(argPacket)); break; diff --git a/README.txt b/instructions.txt similarity index 100% rename from README.txt rename to instructions.txt diff --git a/makefile b/makefile index 0c09a5e..bc3a86b 100644 --- a/makefile +++ b/makefile @@ -20,7 +20,7 @@ release: clean all package #For use on my machine ONLY package: rar a -r -ep Tortuga.rar $(OUTDIR)/*.exe $(OUTDIR)/*.dll - rar a -r Tortuga.rar rsc/* copyright.txt README.txt + rar a -r Tortuga.rar rsc/* copyright.txt instructions.txt $(OUTDIR): mkdir $(OUTDIR) diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index bdb0974..f01924f 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -4,6 +4,7 @@ mapMaker = require("map_maker") mapSaver = require("map_saver") roomSystem = require("room_system") characterSystem = require("character_system") +networkSystem = require("network") local function dumpTable(t) print(t) @@ -18,12 +19,19 @@ roomSystem.RoomManager.SetOnCreate(function(room, index) --called ~60 times per second roomSystem.Room.SetOnTick(room, function(room) + --[[ local character = characterSystem.CharacterManager.GetCharacter("handle") if character ~= nil then --debugging - local x, y = characterSystem.Character.GetOrigin(character) - print("character.Origin(x, y): ", x, y) + local originX, originY = characterSystem.Character.GetOrigin(character) + local motionX, motionY = characterSystem.Character.GetMotion(character) + if motionY < 0 then + characterSystem.Character.SetMotion(character, motionX, 0) + networkSystem.PumpCharacterUpdate(character) + print("Sending: ", motionX, motionY) + end end + --]] end) end) diff --git a/server/entities/entity_api.cpp b/server/entities/entity_api.cpp index a7f71bd..8669417 100644 --- a/server/entities/entity_api.cpp +++ b/server/entities/entity_api.cpp @@ -56,8 +56,8 @@ static int getOrigin(lua_State* L) { static int getMotion(lua_State* L) { Entity* entity = static_cast(lua_touserdata(L, 1)); - lua_pushnumber(L, entity->GetOrigin().x); - lua_pushnumber(L, entity->GetOrigin().y); + lua_pushnumber(L, entity->GetMotion().x); + lua_pushnumber(L, entity->GetMotion().y); return 2; } diff --git a/server/network_api.cpp b/server/network_api.cpp index f78bd90..9975cd0 100644 --- a/server/network_api.cpp +++ b/server/network_api.cpp @@ -21,8 +21,45 @@ */ #include "network_api.hpp" +#include "character_data.hpp" +#include "character_manager.hpp" +#include "server_utilities.hpp" + static int pumpCharacterUpdate(lua_State* L) { - return 0; + CharacterData* characterData = static_cast(lua_touserdata(L, 1)); + + //determine the character's index + int index = -1; + for (auto const& it : *CharacterManager::GetSingleton().GetContainer()) { + if(characterData == &it.second) { + index = it.first; + break; + } + } + + //signal an error + if (index == -1) { + lua_pushboolean(L, false); + return 1; + } + + //fill the packet with all of this character's data + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_UPDATE; + newPacket.characterIndex = index; + strncpy(newPacket.handle, characterData->GetHandle().c_str(), PACKET_STRING_SIZE); + strncpy(newPacket.avatar, characterData->GetAvatar().c_str(), PACKET_STRING_SIZE); + newPacket.accountIndex = characterData->GetOwner(); + newPacket.roomIndex = characterData->GetRoomIndex(); + newPacket.origin = characterData->GetOrigin(); + newPacket.motion = characterData->GetMotion(); + + //pump to the room + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); + + //signal success + lua_pushboolean(L, true); + return 1; } static const luaL_Reg networkLib[] = { @@ -33,5 +70,4 @@ static const luaL_Reg networkLib[] = { LUAMOD_API int openNetworkAPI(lua_State* L) { luaL_newlib(L, networkLib); return 1; - } \ No newline at end of file diff --git a/server/server_application.hpp b/server/server_application.hpp index d53ed32..3ba2b39 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -38,6 +38,9 @@ #include "serial_packet.hpp" #include "singleton.hpp" +//server utilities +#include "server_utilities.hpp" + //APIs #include "lua.hpp" #include "sqlite3.h" @@ -111,13 +114,7 @@ private: void hTextWhisper(TextPacket* const); //utility methods - void PumpPacket(SerialPacket* const); - void PumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position, int distance); - void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); void SaveServerState(); - void FullClientUnload(int index); - void FullAccountUnload(int index); - void FullCharacterUnload(int index); //APIs and utilities sqlite3* database = nullptr; diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index 38127e1..2d701cc 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -46,13 +46,14 @@ void ServerApplication::hCharacterCreate(CharacterPacket* const argPacket) { } //push to the rooms - roomMgr.PushCharacter(characterMgr.Get(characterIndex)); + CharacterData* characterData = characterMgr.Get(characterIndex); + roomMgr.PushCharacter(characterData); //pump this character to all clients CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, characterIndex); + copyCharacterToPacket(&newPacket, characterIndex); newPacket.type = SerialPacketType::CHARACTER_CREATE; - PumpPacket(&newPacket); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } void ServerApplication::hCharacterDelete(CharacterPacket* const argPacket) { @@ -90,16 +91,17 @@ void ServerApplication::hCharacterDelete(CharacterPacket* const argPacket) { } //pop from the rooms - roomMgr.PopCharacter(characterMgr.Get(characterIndex)); - - //delete the character - characterMgr.Delete(characterIndex); + CharacterData* characterData = characterMgr.Get(characterIndex); + roomMgr.PopCharacter(characterData); //pump character delete CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_DELETE; newPacket.characterIndex = characterIndex; - PumpPacket(static_cast(&newPacket)); + pumpPacketProximity(static_cast(&newPacket), characterData->GetRoomIndex()); + + //delete the character + characterMgr.Delete(characterIndex); } void ServerApplication::hCharacterLoad(CharacterPacket* const argPacket) { @@ -126,13 +128,14 @@ void ServerApplication::hCharacterLoad(CharacterPacket* const argPacket) { } //push to the rooms - roomMgr.PushCharacter(characterMgr.Get(characterIndex)); + CharacterData* characterData = characterMgr.Get(characterIndex); + roomMgr.PushCharacter(characterData); //pump this character to all clients CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, characterIndex); + copyCharacterToPacket(&newPacket, characterIndex); newPacket.type = SerialPacketType::CHARACTER_CREATE; - PumpPacket(&newPacket); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { @@ -161,14 +164,14 @@ void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { //pop from the rooms roomMgr.PopCharacter(characterData); - //unload the character - characterMgr.Unload(argPacket->characterIndex); - //pump character delete CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_DELETE; newPacket.characterIndex = argPacket->characterIndex; - PumpPacket(static_cast(&newPacket)); + pumpPacketProximity(static_cast(&newPacket), characterData->GetRoomIndex()); + + //unload the character + characterMgr.Unload(argPacket->characterIndex); } //------------------------- @@ -180,10 +183,15 @@ void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { //get the specified objects AccountData* accountData = accountMgr.Get(argPacket->accountIndex); + + if (!accountData) { + throw(std::runtime_error("Failed to move a character, missing account")); + } + CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); - if (!accountData || !characterData) { - throw(std::runtime_error("Failed to move a character, missing data")); + if (!characterData) { + throw(std::runtime_error("Failed to move a character, missing character")); } //get this account's client @@ -206,9 +214,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { if (characterData->GetRoomIndex() != argPacket->roomIndex) { //delete from the old room CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + copyCharacterToPacket(&newPacket, argPacket->characterIndex); newPacket.type = SerialPacketType::CHARACTER_DELETE; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); //move the character between rooms roomMgr.PopCharacter(characterData); @@ -216,9 +224,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { roomMgr.PushCharacter(characterData); //create in the new room - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + copyCharacterToPacket(&newPacket, argPacket->characterIndex); newPacket.type = SerialPacketType::CHARACTER_CREATE; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } //if not moving between rooms else { @@ -228,9 +236,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { //update the clients CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + copyCharacterToPacket(&newPacket, argPacket->characterIndex); newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + pumpPacketProximity(&newPacket, characterData->GetRoomIndex()); } } diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 36c5bf0..c35fbaa 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -138,7 +138,7 @@ void ServerApplication::hLogoutRequest(ClientPacket* const argPacket) { network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); //save and unload this account and it's characters - FullAccountUnload(argPacket->accountIndex); + fullAccountUnload(argPacket->accountIndex); //finished this routine std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; @@ -165,7 +165,7 @@ void ServerApplication::hDisconnectRequest(ClientPacket* const argPacket) { network.SendTo(clientData->GetAddress(), static_cast(&newPacket)); //unload the client, it's accounts, and their characters - FullClientUnload(argPacket->clientIndex); + fullClientUnload(argPacket->clientIndex); //finished this routine std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; diff --git a/server/server_data_queries.cpp b/server/server_data_queries.cpp index 1019223..7b04ad0 100644 --- a/server/server_data_queries.cpp +++ b/server/server_data_queries.cpp @@ -69,7 +69,7 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket) if (argPacket->roomIndex != -1 && it.second.GetRoomIndex() != argPacket->roomIndex) { continue; } - CopyCharacterToPacket(&newPacket, it.first); + copyCharacterToPacket(&newPacket, it.first); newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 32bb812..8a0bd24 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -188,7 +188,7 @@ void ServerApplication::Proc() { //Check client connections std::list disconnections = clientMgr.CheckConnections(); for(auto const& it : disconnections) { - FullClientUnload(it); + fullClientUnload(it); std::cerr << "Client dropped: " << it << std::endl; } diff --git a/server/server_methods.cpp b/server/server_methods.cpp index d440153..3bcfc96 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -78,7 +78,7 @@ void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { TextPacket newPacket; newPacket.type = SerialPacketType::ADMIN_DISCONNECT_FORCED; strncpy(newPacket.text, "Server shutdown", PACKET_STRING_SIZE); - PumpPacket(&newPacket); + pumpPacket(&newPacket); //finished this routine std::cout << "Shutdown signal accepted" << std::endl; @@ -87,118 +87,3 @@ void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { void ServerApplication::SaveServerState() { //TODO: (9) empty } - -//------------------------- -//full unload methods -//------------------------- - -void ServerApplication::FullClientUnload(int index) { - clientMgr.UnloadIf([&](std::pair client) -> bool { - //skip the wrong clients - if (client.first != index) { - return false; - } - - //unload associated accounts - for (std::map::iterator it = accountMgr.GetContainer()->begin(); it != accountMgr.GetContainer()->end(); /* EMPTY */) { - if (it->second.GetClientIndex() == index) { - FullAccountUnload(it->first); - it = accountMgr.GetContainer()->begin(); - } - else { - ++it; - } - } - - //unload this client - return true; - }); -} - -void ServerApplication::FullAccountUnload(int index) { - accountMgr.UnloadIf([&](std::pair account) -> bool { - //skip the wrong accounts - if (account.first != index) { - return false; - } - - //unload associated characters - for (std::map::iterator it = characterMgr.GetContainer()->begin(); it != characterMgr.GetContainer()->end(); /* EMPTY */) { - if (it->second.GetOwner() == index) { - FullCharacterUnload(it->first); - it = characterMgr.GetContainer()->begin(); - } - else { - ++it; - } - } - - //unload this account - return true; - }); -} - -void ServerApplication::FullCharacterUnload(int index) { - characterMgr.UnloadIf([&](std::pair character) -> bool { - //skip the wrong characters - if (character.first != index) { - return false; - } - - //pop from the rooms - roomMgr.PopCharacter(&character.second); - - //pump character unload - CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_DELETE; - newPacket.characterIndex = character.first; - //NOTE: more character info as needed - - PumpPacket(&newPacket); - - //unload this character - return true; - }); -} - -//------------------------- -//utility methods -//------------------------- - -void ServerApplication::PumpPacket(SerialPacket* const argPacket) { - for (auto& it : *clientMgr.GetContainer()) { - network.SendTo(it.second.GetAddress(), argPacket); - } -} - -void ServerApplication::PumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position, int distance) { - RoomData* room = roomMgr.Get(roomIndex); - - if (!room) { - throw(std::runtime_error("Failed to pump to a non-existant room")); - } - - for (auto& character : *room->GetCharacterList()) { - if (distance == -1 || (character->GetOrigin() - position).Length() <= distance) { - AccountData* account = accountMgr.Get(character->GetOwner()); - ClientData* client = clientMgr.Get(account->GetClientIndex()); - network.SendTo(client->GetAddress(), argPacket); - } - } -} - -void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { - CharacterData* character = characterMgr.Get(characterIndex); - if (!character) { - throw(std::runtime_error("Failed to copy a character to a packet")); - } - - //NOTE: keep this up to date when the character changes - packet->characterIndex = characterIndex; - 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(); -} diff --git a/server/server_utilities/makefile b/server/server_utilities/makefile index 8d12afe..879e339 100644 --- a/server/server_utilities/makefile +++ b/server/server_utilities/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. +INCLUDES+=. ../accounts ../characters ../clients ../entities ../monsters ../rooms ../waypoints ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/server_utilities/server_utilities.cpp b/server/server_utilities/server_utilities.cpp new file mode 100644 index 0000000..58b81ee --- /dev/null +++ b/server/server_utilities/server_utilities.cpp @@ -0,0 +1,151 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * 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_utilities.hpp" + +#include "account_manager.hpp" +#include "character_manager.hpp" +#include "client_manager.hpp" +#include "room_manager.hpp" +#include "udp_network_utility.hpp" + +//------------------------- +//manager unload functions +//------------------------- + +void fullClientUnload(int index) { + ClientManager::GetSingleton().UnloadIf([index](std::pair clientPair) -> bool { + //skip the wrong clients + if (clientPair.first != index) { + return false; + } + + AccountManager& accountMgr = AccountManager::GetSingleton(); + + //unload associated accounts + for (std::map::iterator it = accountMgr.GetContainer()->begin(); it != accountMgr.GetContainer()->end(); /* EMPTY */) { + if (it->second.GetClientIndex() == index) { + fullAccountUnload(it->first); + it = accountMgr.GetContainer()->begin(); + } + else { + ++it; + } + } + + //unload this client + return true; + }); +} + +void fullAccountUnload(int index) { + AccountManager::GetSingleton().UnloadIf([index](std::pair accountPair) -> bool { + //skip the wrong accounts + if (accountPair.first != index) { + return false; + } + + CharacterManager& characterMgr = CharacterManager::GetSingleton(); + + //unload associated characters + for (std::map::iterator it = characterMgr.GetContainer()->begin(); it != characterMgr.GetContainer()->end(); /* EMPTY */) { + if (it->second.GetOwner() == index) { + fullCharacterUnload(it->first); + it = characterMgr.GetContainer()->begin(); + } + else { + ++it; + } + } + + //unload this account + return true; + }); +} + +void fullCharacterUnload(int index) { + CharacterManager::GetSingleton().UnloadIf([index](std::pair characterPair) -> bool { + //skip the wrong characters + if (characterPair.first != index) { + return false; + } + + //pop from the rooms + RoomManager::GetSingleton().PopCharacter(&characterPair.second); + + //pump character unload + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_DELETE; + newPacket.characterIndex = characterPair.first; + //NOTE: more character info as needed + + //TODO: proximity? + pumpPacketProximity(&newPacket, characterPair.second.GetRoomIndex()); + + //unload this character + return true; + }); +} + +//------------------------- +//utility functions +//------------------------- + +void pumpPacket(SerialPacket* const argPacket) { + for (auto& it : *ClientManager::GetSingleton().GetContainer()) { + UDPNetworkUtility::GetSingleton().SendTo(it.second.GetAddress(), argPacket); + } +} + +void pumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position, int distance) { + RoomData* roomData = RoomManager::GetSingleton().Get(roomIndex); + + if (!roomData) { + throw(std::runtime_error("Failed to pump to a non-existant room")); + } + + AccountData* accountData = nullptr; + ClientData* clientData = nullptr; + + for (auto& characterIt : *roomData->GetCharacterList()) { + if (distance == -1 || (characterIt->GetOrigin() - position).Length() <= distance) { + accountData = AccountManager::GetSingleton().Get(characterIt->GetOwner()); + clientData = ClientManager::GetSingleton().Get(accountData->GetClientIndex()); + UDPNetworkUtility::GetSingleton().SendTo(clientData->GetAddress(), argPacket); + } + } +} + +void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { + CharacterData* characterData = CharacterManager::GetSingleton().Get(characterIndex); + if (!characterData) { + throw(std::runtime_error("Failed to copy a character to a packet")); + } + + //NOTE: keep this up to date when the character changes + packet->characterIndex = characterIndex; + strncpy(packet->handle, characterData->GetHandle().c_str(), PACKET_STRING_SIZE); + strncpy(packet->avatar, characterData->GetAvatar().c_str(), PACKET_STRING_SIZE); + packet->accountIndex = characterData->GetOwner(); + packet->roomIndex = characterData->GetRoomIndex(); + packet->origin = characterData->GetOrigin(); + packet->motion = characterData->GetMotion(); +} diff --git a/server/server_utilities/server_utilities.hpp b/server/server_utilities/server_utilities.hpp new file mode 100644 index 0000000..7da41c6 --- /dev/null +++ b/server/server_utilities/server_utilities.hpp @@ -0,0 +1,35 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * 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 SERVERUTILITIES_HPP_ +#define SERVERUTILITIES_HPP_ + +#include "serial_packet.hpp" +#include "vector2.hpp" + +void fullClientUnload(int index); +void fullAccountUnload(int index); +void fullCharacterUnload(int index); +void pumpPacket(SerialPacket* const argPacket); +void pumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position = {0, 0}, int distance = -1); +void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex); + +#endif \ No newline at end of file