From da60fa8f944d88fb44db347459a0f0d07af4476e Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 4 Jun 2014 20:46:05 +1000 Subject: [PATCH 01/34] Began reworking the network code This commit devides SerialPacket into a series of different structures, all decended from a common base class. Using a union was not a good idea. --- common/gameplay/combat_data.hpp | 11 +- common/gameplay/room_data.hpp | 6 + common/gameplay/sanity_check.cpp | 3 - common/network/packet/character_packet.hpp | 53 ++++++ common/network/packet/client_packet.hpp | 34 ++++ common/network/packet/combat_packet.hpp | 46 +++++ common/network/packet/enemy_packet.hpp | 39 ++++ common/network/packet/makefile | 37 ++++ common/network/packet/region_packet.hpp | 38 ++++ common/network/packet/sanity_check.cpp | 28 +++ common/network/packet/serial_packet.hpp | 34 ++++ common/network/packet/serial_packet_base.hpp | 46 +++++ common/network/packet/serial_packet_type.hpp | 98 ++++++++++ common/network/packet/server_packet.hpp | 34 ++++ common/network/serial.cpp | 8 +- common/network/serial_packet.hpp | 188 ------------------- todo.txt | 3 + 17 files changed, 505 insertions(+), 201 deletions(-) create mode 100644 common/network/packet/character_packet.hpp create mode 100644 common/network/packet/client_packet.hpp create mode 100644 common/network/packet/combat_packet.hpp create mode 100644 common/network/packet/enemy_packet.hpp create mode 100644 common/network/packet/makefile create mode 100644 common/network/packet/region_packet.hpp create mode 100644 common/network/packet/sanity_check.cpp create mode 100644 common/network/packet/serial_packet.hpp create mode 100644 common/network/packet/serial_packet_base.hpp create mode 100644 common/network/packet/serial_packet_type.hpp create mode 100644 common/network/packet/server_packet.hpp delete mode 100644 common/network/serial_packet.hpp diff --git a/common/gameplay/combat_data.hpp b/common/gameplay/combat_data.hpp index db87851..3c45b78 100644 --- a/common/gameplay/combat_data.hpp +++ b/common/gameplay/combat_data.hpp @@ -35,11 +35,11 @@ //std namespace #include -#include +#include #include -#define COMBAT_MAX_CHARACTER_COUNT 12 -#define COMBAT_MAX_ENEMY_COUNT 12 +#define COMBAT_MAX_CHARACTERS 12 +#define COMBAT_MAX_ENEMIES 12 struct CombatData { enum class Terrain { @@ -50,9 +50,8 @@ struct CombatData { typedef std::chrono::steady_clock Clock; - //combatants, point to the std::map's internal pairs - std::list*> characterList; - std::list*> enemyList; + std::array characterArray; + std::array enemyArray; //world interaction int mapIndex = 0; diff --git a/common/gameplay/room_data.hpp b/common/gameplay/room_data.hpp index ae49465..6826314 100644 --- a/common/gameplay/room_data.hpp +++ b/common/gameplay/room_data.hpp @@ -30,6 +30,12 @@ struct RoomData { FORESTS, CAVES, }; + + /* TODO: more + * "multiple rooms system" using this structure + * Pager + * collision map + */ }; #endif diff --git a/common/gameplay/sanity_check.cpp b/common/gameplay/sanity_check.cpp index 1e20ccf..719db9f 100644 --- a/common/gameplay/sanity_check.cpp +++ b/common/gameplay/sanity_check.cpp @@ -31,7 +31,4 @@ * Since most/all of the files in this directory are header files, I've created * this source file as a "sanity check", to ensure that the above header files * are written correctly via make. - * - * Oddly enough, I'm pretty sure this is the first directory compiled in a - * clean build. */ \ No newline at end of file diff --git a/common/network/packet/character_packet.hpp b/common/network/packet/character_packet.hpp new file mode 100644 index 0000000..3b44d9b --- /dev/null +++ b/common/network/packet/character_packet.hpp @@ -0,0 +1,53 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 CHARACTERPACKET_HPP_ +#define CHARACTERPACKET_HPP_ + +#include "serial_packet_base.hpp" + +#include "vector2.hpp" +#include "statistics.hpp" + +struct CharacterPacket : SerialPacketBase { + //identify the character + int characterIndex; + char handle[PACKET_STRING_SIZE]; + char avatar[PACKET_STRING_SIZE]; + + //the owner + int accountIndex; + + //location + int roomIndex; + Vector2 origin; + Vector2 motion; + + //gameplay + Statistics stats; + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs +}; + +#endif \ No newline at end of file diff --git a/common/network/packet/client_packet.hpp b/common/network/packet/client_packet.hpp new file mode 100644 index 0000000..995bc4a --- /dev/null +++ b/common/network/packet/client_packet.hpp @@ -0,0 +1,34 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 CLIENTPACKET_HPP_ +#define CLIENTPACKET_HPP_ + +#include "serial_packet_base.hpp" + +struct ClientPacket : SerialPacketBase { + int clientIndex; + int accountIndex; + char username[PACKET_STRING_SIZE]; + char password[PACKET_STRING_SIZE]; //hashed, not currently used +}; + +#endif \ No newline at end of file diff --git a/common/network/packet/combat_packet.hpp b/common/network/packet/combat_packet.hpp new file mode 100644 index 0000000..a95ca25 --- /dev/null +++ b/common/network/packet/combat_packet.hpp @@ -0,0 +1,46 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 COMBATPACKET_HPP_ +#define COMBATPACKET_HPP_ + +#include "serial_packet_base.hpp" + +#include "combat_data.hpp" + +struct CombatPacket : SerialPacketBase { + //identify the combat instance + int combatIndex; + int difficulty; + CombatData::Terrain terrainType; + + //combatants + int characterArray[COMBAT_MAX_CHARACTERS]; + int enemyArray[COMBAT_MAX_ENEMIES]; + + //location + int mapIndex; + Vector2 origin; + + //TODO: rewards +}; + +#endif \ No newline at end of file diff --git a/common/network/packet/enemy_packet.hpp b/common/network/packet/enemy_packet.hpp new file mode 100644 index 0000000..bbe68c9 --- /dev/null +++ b/common/network/packet/enemy_packet.hpp @@ -0,0 +1,39 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 ENEMYPACKET_HPP_ +#define ENEMYPACKET_HPP_ + +#include "serial_packet_base.hpp" + +struct EnemyPacket : SerialPacketBase { + //identify the enemy + int enemyIndex; + char handle[PACKET_STRING_SIZE]; + char avatar[PACKET_STRING_SIZE]; + + //gameplay + Statistics stats; + + //TODO: rewards +}; + +#endif \ No newline at end of file diff --git a/common/network/packet/makefile b/common/network/packet/makefile new file mode 100644 index 0000000..f993f8b --- /dev/null +++ b/common/network/packet/makefile @@ -0,0 +1,37 @@ +#config +INCLUDES+=. ../../gameplay ../../map ../../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)/,libcommon.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/common/network/packet/region_packet.hpp b/common/network/packet/region_packet.hpp new file mode 100644 index 0000000..8a9085e --- /dev/null +++ b/common/network/packet/region_packet.hpp @@ -0,0 +1,38 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 REGIONPACKET_HPP_ +#define REGIONPACKET_HPP_ + +#include "serial_packet_base.hpp" + +#include "region.hpp" + +struct RegionPacket : SerialPacketBase { + //location/identify the region + int roomIndex; + int x, y; + + //the data + Region* region; +}; + +#endif \ No newline at end of file diff --git a/common/network/packet/sanity_check.cpp b/common/network/packet/sanity_check.cpp new file mode 100644 index 0000000..f250d69 --- /dev/null +++ b/common/network/packet/sanity_check.cpp @@ -0,0 +1,28 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 "serial_packet.hpp" + +/* DOCS: Sanity check, read more + * Since most/all of the files in this directory are header files, I've created + * this source file as a "sanity check", to ensure that the above header files + * are written correctly via make. +*/ diff --git a/common/network/packet/serial_packet.hpp b/common/network/packet/serial_packet.hpp new file mode 100644 index 0000000..7b7137f --- /dev/null +++ b/common/network/packet/serial_packet.hpp @@ -0,0 +1,34 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 SERIALPACKET_HPP_ +#define SERIALPACKET_HPP_ + +#include "character_packet.hpp" +#include "client_packet.hpp" +#include "combat_packet.hpp" +#include "enemy_packet.hpp" +#include "region_packet.hpp" +#include "server_packet.hpp" + +//NOTE: SerialPacket is defined in serial_packet_base.hpp + +#endif diff --git a/common/network/packet/serial_packet_base.hpp b/common/network/packet/serial_packet_base.hpp new file mode 100644 index 0000000..742c4db --- /dev/null +++ b/common/network/packet/serial_packet_base.hpp @@ -0,0 +1,46 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 SERIALPACKETBASE_HPP_ +#define SERIALPACKETBASE_HPP_ + +#ifndef SERIALPACKET_HPP_ + #error Cannot include this file without 'serial_packet.hpp' +#endif + +#include "serial_packet_type.hpp" + +#include "SDL/SDL_net.h" + +#define PACKET_STRING_SIZE 100 + +struct SerialPacketBase { + //members + SerialPacketType type; + IPaddress srcAddress; + + typedef SerialPacketType Type; +}; + +typedef SerialPacketBase* SerialPacket; +typedef SerialPacketType PacketType; + +#endif diff --git a/common/network/packet/serial_packet_type.hpp b/common/network/packet/serial_packet_type.hpp new file mode 100644 index 0000000..8fbcd17 --- /dev/null +++ b/common/network/packet/serial_packet_type.hpp @@ -0,0 +1,98 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 SERIALPACKETTYPE_HPP_ +#define SERIALPACKETTYPE_HPP_ + +enum class SerialPacketType { + //default: there is something wrong + NONE = 0, + + //keep alive + PING, + PONG, + + //searching for a server to join + BROADCAST_REQUEST, + BROADCAST_RESPONSE, + BROADCAST_REJECTION, + + //try to join the server + JOIN_REQUEST, + JOIN_RESPONSE, + JOIN_REJECTION, + + //mass update + SYNCHRONIZE, + + //disconnect from the server + DISCONNECT, + + //shut down the server + SHUTDOWN, + + //map data + REGION_REQUEST, + REGION_CONTENT, + REGION_REJECTION, + + //combat data + COMBAT_NEW, + COMBAT_DELETE, + COMBAT_UPDATE, + + COMBAT_ENTER_REQUEST, + COMBAT_ENTER_RESPONSE, + + COMBAT_EXIT_REQUEST, + COMBAT_EXIT_RESPONSE, + + //TODO: COMBAT info + + COMBAT_REJECTION, + + //character data + CHARACTER_NEW, + CHARACTER_DELETE, + CHARACTER_UPDATE, + + CHARACTER_STATS_REQUEST, + CHARACTER_STATS_RESPONSE, + + CHARACTER_REJECTION, + + //enemy data + ENEMY_NEW, + ENEMY_DELETE, + ENEMY_UPDATE, + + ENEMY_STATS_REQUEST, + ENEMY_STATS_RESPONSE, + + ENEMY_REJECTION, + + //more packet types go here + + //not used + LAST, +}; + +#endif \ No newline at end of file diff --git a/common/network/packet/server_packet.hpp b/common/network/packet/server_packet.hpp new file mode 100644 index 0000000..fcd4a49 --- /dev/null +++ b/common/network/packet/server_packet.hpp @@ -0,0 +1,34 @@ +/* Copyright: (c) Kayne Ruse 2013, 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 SERVERPACKET_HPP_ +#define SERVERPACKET_HPP_ + +#include "serial_packet_base.hpp" + +struct ServerPacket : SerialPacketBase { + //identify the server + char name[PACKET_STRING_SIZE]; + int playerCount; + int version; +}; + +#endif \ No newline at end of file diff --git a/common/network/serial.cpp b/common/network/serial.cpp index 961afd4..6e75c5a 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -103,8 +103,8 @@ void serializeCombat(SerialPacket* packet, char* buffer) { SERIALIZE(buffer, &packet->combatInfo.terrainType, sizeof(CombatData::Terrain)); //arrays - SERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTER_COUNT); - SERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMY_COUNT); + SERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTERS); + SERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMIES); //position SERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); @@ -247,8 +247,8 @@ void deserializeCombat(SerialPacket* packet, char* buffer) { DESERIALIZE(buffer, &packet->combatInfo.terrainType, sizeof(CombatData::Terrain)); //arrays - DESERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTER_COUNT); - DESERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMY_COUNT); + DESERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTERS); + DESERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMIES); //position DESERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp deleted file mode 100644 index d378fde..0000000 --- a/common/network/serial_packet.hpp +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013, 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 SERIALPACKET_HPP_ -#define SERIALPACKET_HPP_ - -#include "vector2.hpp" -#include "region.hpp" -#include "statistics.hpp" -#include "combat_data.hpp" - -#include "SDL/SDL_net.h" - -#define NETWORK_VERSION 20140601 -#define PACKET_STRING_SIZE 100 - -//TODO: would it be possible to serialize structures directly? -union SerialPacket { - //types of packets - enum class Type { - //default: there is something wrong - NONE = 0, - - //keep alive - PING, - PONG, - - //searching for a server to join - BROADCAST_REQUEST, - BROADCAST_RESPONSE, - BROADCAST_REJECTION, - - //try to join the server - JOIN_REQUEST, - JOIN_RESPONSE, - JOIN_REJECTION, - - //mass update - SYNCHRONIZE, - - //disconnect from the server - DISCONNECT, - - //shut down the server - SHUTDOWN, - - //map data - REGION_REQUEST, - REGION_CONTENT, - REGION_REJECTION, - - //combat data - COMBAT_NEW, - COMBAT_DELETE, - COMBAT_UPDATE, - - COMBAT_ENTER_REQUEST, - COMBAT_ENTER_RESPONSE, - - COMBAT_EXIT_REQUEST, - COMBAT_EXIT_RESPONSE, - - //TODO: COMBAT info - - COMBAT_REJECTION, - - //character data - CHARACTER_NEW, - CHARACTER_DELETE, - CHARACTER_UPDATE, - - CHARACTER_STATS_REQUEST, - CHARACTER_STATS_RESPONSE, - - CHARACTER_REJECTION, - - //enemy data - ENEMY_NEW, - ENEMY_DELETE, - ENEMY_UPDATE, - - ENEMY_STATS_REQUEST, - ENEMY_STATS_RESPONSE, - - ENEMY_REJECTION, - - //more packet types go here - - //not used - LAST, - }; - - //metadata on the packet itself - struct Metadata { - Type type; - IPaddress srcAddress; - }meta; - - //info about the server - struct ServerInformation { - Metadata meta; - int networkVersion; - char name[PACKET_STRING_SIZE]; - int playerCount; - }serverInfo; - - //info about the client - struct ClientInformation { - Metadata meta; - int clientIndex; - int accountIndex; - int characterIndex; - char username[PACKET_STRING_SIZE]; - //TODO: password - char handle[PACKET_STRING_SIZE]; - char avatar[PACKET_STRING_SIZE]; - }clientInfo; - - //info about a region - struct RegionInformation { - Metadata meta; - int mapIndex; - int x, y; - Region* region; - }regionInfo; - - //info about a combat scenario - struct CombatInformation { - Metadata meta; - int combatIndex; - int difficulty; - CombatData::Terrain terrainType; - int characterArray[COMBAT_MAX_CHARACTER_COUNT]; - int enemyArray[COMBAT_MAX_ENEMY_COUNT]; - int mapIndex; - Vector2 origin; - //TODO: rewards - }combatInfo; - - //info about a character - struct CharacterInformation { - Metadata meta; - int clientIndex; - int accountIndex; - int characterIndex; - char handle[PACKET_STRING_SIZE]; - char avatar[PACKET_STRING_SIZE]; - int mapIndex; - Vector2 origin; - Vector2 motion; - Statistics stats; - }characterInfo; - - //info about an enemy - struct EnemyInformation { - Metadata meta; - char handle[PACKET_STRING_SIZE]; - char avatar[PACKET_STRING_SIZE]; - Statistics stats; - //TODO: rewards - }enemyInfo; - - //defaults - SerialPacket() { - meta.type = Type::NONE; - meta.srcAddress = {0,0}; - } -}; - -#endif diff --git a/todo.txt b/todo.txt index f03386a..fa7d60d 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,6 @@ +TODO: Modulate this god class +TODO: Segment SerialPacket? +TODO: Not all structures in common/gameplay are needed by the client TODO: I need to keep the documentation up to date. Namely, the GDD is getting out of date. TODO: I completely forgot about status ailments TODO: Time delay for requesting region packets From 23364b28109d33ee995e1592bd277ea84901a25d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 4 Jun 2014 23:03:24 +1000 Subject: [PATCH 02/34] Split up the serial code, but had to gut it in the process Since the contents of the packets are different than before, I decided to gut the serialization code. I'll reimplement the internals soon. --- common/network/packet/serial_packet_base.hpp | 5 +- common/network/serial.cpp | 473 ------------------ common/network/serial/makefile | 37 ++ common/network/serial/serial.cpp | 188 +++++++ common/network/serial/serial.hpp | 65 +++ common/network/serial/serial_character.cpp | 44 ++ common/network/serial/serial_client.cpp | 36 ++ common/network/serial/serial_combat.cpp | 36 ++ common/network/serial/serial_enemy.cpp | 44 ++ common/network/serial/serial_region.cpp | 89 ++++ common/network/serial/serial_server.cpp | 36 ++ common/network/serial/serial_statistics.cpp | 65 +++ .../{serial.hpp => serial/serial_util.hpp} | 19 +- 13 files changed, 649 insertions(+), 488 deletions(-) delete mode 100644 common/network/serial.cpp create mode 100644 common/network/serial/makefile create mode 100644 common/network/serial/serial.cpp create mode 100644 common/network/serial/serial.hpp create mode 100644 common/network/serial/serial_character.cpp create mode 100644 common/network/serial/serial_client.cpp create mode 100644 common/network/serial/serial_combat.cpp create mode 100644 common/network/serial/serial_enemy.cpp create mode 100644 common/network/serial/serial_region.cpp create mode 100644 common/network/serial/serial_server.cpp create mode 100644 common/network/serial/serial_statistics.cpp rename common/network/{serial.hpp => serial/serial_util.hpp} (60%) diff --git a/common/network/packet/serial_packet_base.hpp b/common/network/packet/serial_packet_base.hpp index 742c4db..16279c8 100644 --- a/common/network/packet/serial_packet_base.hpp +++ b/common/network/packet/serial_packet_base.hpp @@ -38,9 +38,10 @@ struct SerialPacketBase { IPaddress srcAddress; typedef SerialPacketType Type; + + virtual ~SerialPacketBase(); }; -typedef SerialPacketBase* SerialPacket; -typedef SerialPacketType PacketType; +typedef SerialPacketBase SerialPacket; #endif diff --git a/common/network/serial.cpp b/common/network/serial.cpp deleted file mode 100644 index 6e75c5a..0000000 --- a/common/network/serial.cpp +++ /dev/null @@ -1,473 +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 "serial.hpp" - -#include "map_allocator.hpp" -#include "statistics.hpp" - -#include - -//------------------------- -//Convenience Macros -//------------------------- - -#define SERIALIZE(buffer, data, size) memcpy(buffer, data, size); buffer += size; -#define DESERIALIZE(buffer, data, size) memcpy(data, buffer, size); buffer += size; - -//------------------------- -//internal serialization functions -//------------------------- - -void serializeType(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); -} - -void serializeServer(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //server info - SERIALIZE(buffer, &packet->serverInfo.networkVersion, sizeof(int)); - SERIALIZE(buffer, packet->serverInfo.name, PACKET_STRING_SIZE); - SERIALIZE(buffer, &packet->serverInfo.playerCount, sizeof(int)); -} - -void serializeClient(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //indexes - SERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int)); - SERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int)); - SERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int)); - - //texts - SERIALIZE(buffer, packet->clientInfo.username, PACKET_STRING_SIZE); - //TODO: password - SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); - SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); -} - -void serializeRegionFormat(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //format - SERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int)); - SERIALIZE(buffer, &packet->regionInfo.x, sizeof(int)); - SERIALIZE(buffer, &packet->regionInfo.y, sizeof(int)); -} - -void serializeRegionContent(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //format - SERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int)); - SERIALIZE(buffer, &packet->regionInfo.x, sizeof(int)); - SERIALIZE(buffer, &packet->regionInfo.y, sizeof(int)); - - //content - for (register int i = 0; i < REGION_WIDTH; i++) { - for (register int j = 0; j < REGION_HEIGHT; j++) { - for (register int k = 0; k < REGION_DEPTH; k++) { - *reinterpret_cast(buffer) = packet->regionInfo.region->GetTile(i, j, k); - buffer += sizeof(Region::type_t); - } - } - } -} - -void serializeCombat(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //integers - SERIALIZE(buffer, &packet->combatInfo.combatIndex, sizeof(int)); - SERIALIZE(buffer, &packet->combatInfo.difficulty, sizeof(int)); - - SERIALIZE(buffer, &packet->combatInfo.terrainType, sizeof(CombatData::Terrain)); - - //arrays - SERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTERS); - SERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMIES); - - //position - SERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); - SERIALIZE(buffer, &packet->combatInfo.origin.x, sizeof(double)); - SERIALIZE(buffer, &packet->combatInfo.origin.y, sizeof(double)); - - //TODO: rewards -} - -void serializeStatistics(Statistics* stats, char* buffer) { - //integers - SERIALIZE(buffer, &stats->level, sizeof(int)); - SERIALIZE(buffer, &stats->exp, sizeof(int)); - SERIALIZE(buffer, &stats->maxHP, sizeof(int)); - SERIALIZE(buffer, &stats->health, sizeof(int)); - SERIALIZE(buffer, &stats->maxMP, sizeof(int)); - SERIALIZE(buffer, &stats->mana, sizeof(int)); - SERIALIZE(buffer, &stats->attack, sizeof(int)); - SERIALIZE(buffer, &stats->defence, sizeof(int)); - SERIALIZE(buffer, &stats->intelligence, sizeof(int)); - SERIALIZE(buffer, &stats->resistance, sizeof(int)); - SERIALIZE(buffer, &stats->speed, sizeof(int)); - - //floats - SERIALIZE(buffer, &stats->accuracy, sizeof(float)); - SERIALIZE(buffer, &stats->evasion, sizeof(float)); - SERIALIZE(buffer, &stats->luck, sizeof(float)); -} - -void serializeCharacter(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //indexes - SERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int)); - SERIALIZE(buffer, &packet->characterInfo.accountIndex, sizeof(int)); - SERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int)); - - //texts - SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); - SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); - - //vectors - SERIALIZE(buffer, &packet->characterInfo.origin.x, sizeof(double)); - SERIALIZE(buffer, &packet->characterInfo.origin.y, sizeof(double)); - SERIALIZE(buffer, &packet->characterInfo.motion.x, sizeof(double)); - SERIALIZE(buffer, &packet->characterInfo.motion.y, sizeof(double)); - - //stats structure - serializeStatistics(&packet->characterInfo.stats, buffer); - buffer += sizeof(Statistics); -} - -void serializeEnemy(SerialPacket* packet, char* buffer) { - SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //texts - SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); - SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); - - //stats structure - serializeStatistics(&packet->characterInfo.stats, buffer); - buffer += sizeof(Statistics); -} - -//------------------------- -//internal deserialization functions -//------------------------- - -void deserializeType(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); -} - -void deserializeServer(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //server info - DESERIALIZE(buffer, &packet->serverInfo.networkVersion, sizeof(int)); - DESERIALIZE(buffer, packet->serverInfo.name, PACKET_STRING_SIZE); - DESERIALIZE(buffer, &packet->serverInfo.playerCount, sizeof(int)); -} - -void deserializeClient(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //indexes - DESERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int)); - - //texts - DESERIALIZE(buffer, packet->clientInfo.username, PACKET_STRING_SIZE); - //TODO: password - DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); - DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); -} - -void deserializeRegionFormat(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //format - DESERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->regionInfo.x, sizeof(int)); - DESERIALIZE(buffer, &packet->regionInfo.y, sizeof(int)); -} - -void deserializeRegionContent(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //format - DESERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->regionInfo.x, sizeof(int)); - DESERIALIZE(buffer, &packet->regionInfo.y, sizeof(int)); - - //an object to work on - BlankAllocator().Create( - &packet->regionInfo.region, - packet->regionInfo.x, - packet->regionInfo.y - ); - - //content - for (register int i = 0; i < REGION_WIDTH; i++) { - for (register int j = 0; j < REGION_HEIGHT; j++) { - for (register int k = 0; k < REGION_DEPTH; k++) { - packet->regionInfo.region->SetTile(i, j, k, *reinterpret_cast(buffer)); - buffer += sizeof(Region::type_t); - } - } - } -} - - -void deserializeCombat(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //integers - DESERIALIZE(buffer, &packet->combatInfo.combatIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->combatInfo.difficulty, sizeof(int)); - - DESERIALIZE(buffer, &packet->combatInfo.terrainType, sizeof(CombatData::Terrain)); - - //arrays - DESERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTERS); - DESERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMIES); - - //position - DESERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->combatInfo.origin.x, sizeof(double)); - DESERIALIZE(buffer, &packet->combatInfo.origin.y, sizeof(double)); - - //TODO: rewards -} - - -void deserializeStatistics(Statistics* stats, char* buffer) { - //integers - DESERIALIZE(buffer, &stats->level, sizeof(int)); - DESERIALIZE(buffer, &stats->exp, sizeof(int)); - DESERIALIZE(buffer, &stats->maxHP, sizeof(int)); - DESERIALIZE(buffer, &stats->health, sizeof(int)); - DESERIALIZE(buffer, &stats->maxMP, sizeof(int)); - DESERIALIZE(buffer, &stats->mana, sizeof(int)); - DESERIALIZE(buffer, &stats->attack, sizeof(int)); - DESERIALIZE(buffer, &stats->defence, sizeof(int)); - DESERIALIZE(buffer, &stats->intelligence, sizeof(int)); - DESERIALIZE(buffer, &stats->resistance, sizeof(int)); - DESERIALIZE(buffer, &stats->speed, sizeof(int)); - - //floats - DESERIALIZE(buffer, &stats->accuracy, sizeof(float)); - DESERIALIZE(buffer, &stats->evasion, sizeof(float)); - DESERIALIZE(buffer, &stats->luck, sizeof(float)); -} - -void deserializeCharacter(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //indexes - DESERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->characterInfo.accountIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int)); - - //texts - DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); - DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); - - //vectors - DESERIALIZE(buffer, &packet->characterInfo.origin.x, sizeof(double)); - DESERIALIZE(buffer, &packet->characterInfo.origin.y, sizeof(double)); - DESERIALIZE(buffer, &packet->characterInfo.motion.x, sizeof(double)); - DESERIALIZE(buffer, &packet->characterInfo.motion.y, sizeof(double)); - - //stats structure - deserializeStatistics(&packet->characterInfo.stats, buffer); - buffer += sizeof(Statistics); -} - -void deserializeEnemy(SerialPacket* packet, char* buffer) { - DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type)); - - //texts - DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE); - DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); - - //stats structure - deserializeStatistics(&packet->characterInfo.stats, buffer); - buffer += sizeof(Statistics); -} - -//------------------------- -//the interface functions -//------------------------- - -void serialize(SerialPacket* packet, void* buffer) { - switch(packet->meta.type) { - //no extra data - case SerialPacket::Type::NONE: - case SerialPacket::Type::PING: - case SerialPacket::Type::PONG: - case SerialPacket::Type::BROADCAST_REQUEST: - - //all rejections - case SerialPacket::Type::BROADCAST_REJECTION: - case SerialPacket::Type::JOIN_REJECTION: - case SerialPacket::Type::REGION_REJECTION: - case SerialPacket::Type::CHARACTER_REJECTION: - case SerialPacket::Type::ENEMY_REJECTION: - case SerialPacket::Type::COMBAT_REJECTION: - - serializeType(packet, reinterpret_cast(buffer)); - break; - - //server info - case SerialPacket::Type::BROADCAST_RESPONSE: - serializeServer(packet, reinterpret_cast(buffer)); - break; - - //client info - case SerialPacket::Type::JOIN_REQUEST: - case SerialPacket::Type::JOIN_RESPONSE: - case SerialPacket::Type::SYNCHRONIZE: - case SerialPacket::Type::DISCONNECT: - case SerialPacket::Type::SHUTDOWN: - serializeClient(packet, reinterpret_cast(buffer)); - break; - - //region info - case SerialPacket::Type::REGION_REQUEST: - serializeRegionFormat(packet, reinterpret_cast(buffer)); - break; - - case SerialPacket::Type::REGION_CONTENT: - serializeRegionContent(packet, reinterpret_cast(buffer)); - break; - - //combat info - case SerialPacket::Type::COMBAT_NEW: - case SerialPacket::Type::COMBAT_DELETE: - case SerialPacket::Type::COMBAT_UPDATE: - - //TODO: is this the best fit? - case SerialPacket::Type::COMBAT_ENTER_REQUEST: - case SerialPacket::Type::COMBAT_ENTER_RESPONSE: - case SerialPacket::Type::COMBAT_EXIT_REQUEST: - case SerialPacket::Type::COMBAT_EXIT_RESPONSE: - - serializeCombat(packet, reinterpret_cast(buffer)); - break; - - //character info - case SerialPacket::Type::CHARACTER_NEW: - case SerialPacket::Type::CHARACTER_DELETE: - case SerialPacket::Type::CHARACTER_UPDATE: - case SerialPacket::Type::CHARACTER_STATS_REQUEST: - case SerialPacket::Type::CHARACTER_STATS_RESPONSE: - serializeCharacter(packet, reinterpret_cast(buffer)); - break; - - //enemy info - case SerialPacket::Type::ENEMY_NEW: - case SerialPacket::Type::ENEMY_DELETE: - case SerialPacket::Type::ENEMY_UPDATE: - case SerialPacket::Type::ENEMY_STATS_REQUEST: - case SerialPacket::Type::ENEMY_STATS_RESPONSE: - serializeEnemy(packet, reinterpret_cast(buffer)); - break; - } -} - -void deserialize(SerialPacket* packet, void* buffer) { - //find the type, so that you can actually deserialize the packet! - deserializeType(packet, reinterpret_cast(buffer)); - switch(packet->meta.type) { - //no extra data - case SerialPacket::Type::NONE: - case SerialPacket::Type::PING: - case SerialPacket::Type::PONG: - case SerialPacket::Type::BROADCAST_REQUEST: - - //all rejections - case SerialPacket::Type::BROADCAST_REJECTION: - case SerialPacket::Type::JOIN_REJECTION: - case SerialPacket::Type::REGION_REJECTION: - case SerialPacket::Type::CHARACTER_REJECTION: - case SerialPacket::Type::ENEMY_REJECTION: - case SerialPacket::Type::COMBAT_REJECTION: - - //NOTHING - break; - - //server info - case SerialPacket::Type::BROADCAST_RESPONSE: - deserializeServer(packet, reinterpret_cast(buffer)); - break; - - //client info - case SerialPacket::Type::JOIN_REQUEST: - case SerialPacket::Type::JOIN_RESPONSE: - case SerialPacket::Type::SYNCHRONIZE: - case SerialPacket::Type::DISCONNECT: - case SerialPacket::Type::SHUTDOWN: - deserializeClient(packet, reinterpret_cast(buffer)); - break; - - //region info - case SerialPacket::Type::REGION_REQUEST: - deserializeRegionFormat(packet, reinterpret_cast(buffer)); - break; - - case SerialPacket::Type::REGION_CONTENT: - deserializeRegionContent(packet, reinterpret_cast(buffer)); - break; - - //combat info - case SerialPacket::Type::COMBAT_NEW: - case SerialPacket::Type::COMBAT_DELETE: - case SerialPacket::Type::COMBAT_UPDATE: - - //TODO: is this the best fit? - case SerialPacket::Type::COMBAT_ENTER_REQUEST: - case SerialPacket::Type::COMBAT_ENTER_RESPONSE: - case SerialPacket::Type::COMBAT_EXIT_REQUEST: - case SerialPacket::Type::COMBAT_EXIT_RESPONSE: - - serializeCombat(packet, reinterpret_cast(buffer)); - break; - - //character info - case SerialPacket::Type::CHARACTER_NEW: - case SerialPacket::Type::CHARACTER_DELETE: - case SerialPacket::Type::CHARACTER_UPDATE: - case SerialPacket::Type::CHARACTER_STATS_REQUEST: - case SerialPacket::Type::CHARACTER_STATS_RESPONSE: - deserializeCharacter(packet, reinterpret_cast(buffer)); - break; - - //enemy info - case SerialPacket::Type::ENEMY_NEW: - case SerialPacket::Type::ENEMY_DELETE: - case SerialPacket::Type::ENEMY_UPDATE: - case SerialPacket::Type::ENEMY_STATS_REQUEST: - case SerialPacket::Type::ENEMY_STATS_RESPONSE: - serializeEnemy(packet, reinterpret_cast(buffer)); - break; - } -} \ No newline at end of file diff --git a/common/network/serial/makefile b/common/network/serial/makefile new file mode 100644 index 0000000..564b228 --- /dev/null +++ b/common/network/serial/makefile @@ -0,0 +1,37 @@ +#config +INCLUDES+=. ../packet ../../gameplay ../../map ../../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)/,libcommon.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/common/network/serial/serial.cpp b/common/network/serial/serial.cpp new file mode 100644 index 0000000..c73b2bc --- /dev/null +++ b/common/network/serial/serial.cpp @@ -0,0 +1,188 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +//simple type functions +void serializeType(SerialPacketBase* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); +} + +void deserializeType(SerialPacketBase* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); +} + +//main switch functions +void serializePacket(SerialPacketBase* packet, void* buffer) { + switch(packet->type) { + //no extra data + case SerialPacketType::NONE: + case SerialPacketType::PING: + case SerialPacketType::PONG: + case SerialPacketType::BROADCAST_REQUEST: + + //all rejections + case SerialPacketType::BROADCAST_REJECTION: + case SerialPacketType::JOIN_REJECTION: + case SerialPacketType::REGION_REJECTION: + case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::ENEMY_REJECTION: + case SerialPacketType::COMBAT_REJECTION: + + serializeType(packet, buffer); + break; + + //character info + case SerialPacketType::CHARACTER_NEW: + case SerialPacketType::CHARACTER_DELETE: + case SerialPacketType::CHARACTER_UPDATE: + case SerialPacketType::CHARACTER_STATS_REQUEST: + case SerialPacketType::CHARACTER_STATS_RESPONSE: + serializeCharacter(dynamic_cast(packet), buffer); + break; + + //client info + case SerialPacketType::JOIN_REQUEST: + case SerialPacketType::JOIN_RESPONSE: + case SerialPacketType::SYNCHRONIZE: + case SerialPacketType::DISCONNECT: + case SerialPacketType::SHUTDOWN: + serializeClient(dynamic_cast(packet), buffer); + break; + + //combat info + case SerialPacketType::COMBAT_NEW: + case SerialPacketType::COMBAT_DELETE: + case SerialPacketType::COMBAT_UPDATE: + + //TODO: is this the best fit? + case SerialPacketType::COMBAT_ENTER_REQUEST: + case SerialPacketType::COMBAT_ENTER_RESPONSE: + case SerialPacketType::COMBAT_EXIT_REQUEST: + case SerialPacketType::COMBAT_EXIT_RESPONSE: + + serializeCombat(dynamic_cast(packet), buffer); + break; + + //enemy info + case SerialPacketType::ENEMY_NEW: + case SerialPacketType::ENEMY_DELETE: + case SerialPacketType::ENEMY_UPDATE: + case SerialPacketType::ENEMY_STATS_REQUEST: + case SerialPacketType::ENEMY_STATS_RESPONSE: + serializeEnemy(dynamic_cast(packet), buffer); + break; + + //region info + case SerialPacketType::REGION_REQUEST: + serializeRegionFormat(dynamic_cast(packet), buffer); + break; + + case SerialPacketType::REGION_CONTENT: + serializeRegionContent(dynamic_cast(packet), buffer); + break; + + //server info + case SerialPacketType::BROADCAST_RESPONSE: + serializeServer(dynamic_cast(packet), buffer); + break; + } +} + +void deserializePacket(SerialPacketBase* packet, void* buffer) { + //find the type, so that you can actually deserialize the packet! + deserializeType(packet, buffer); + switch(packet->type) { + //no extra data + case SerialPacketType::NONE: + case SerialPacketType::PING: + case SerialPacketType::PONG: + case SerialPacketType::BROADCAST_REQUEST: + + //all rejections + case SerialPacketType::BROADCAST_REJECTION: + case SerialPacketType::JOIN_REJECTION: + case SerialPacketType::REGION_REJECTION: + case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::ENEMY_REJECTION: + case SerialPacketType::COMBAT_REJECTION: + + //NOTHING + break; + + //character info + case SerialPacketType::CHARACTER_NEW: + case SerialPacketType::CHARACTER_DELETE: + case SerialPacketType::CHARACTER_UPDATE: + case SerialPacketType::CHARACTER_STATS_REQUEST: + case SerialPacketType::CHARACTER_STATS_RESPONSE: + deserializeCharacter(dynamic_cast(packet), buffer); + break; + + //client info + case SerialPacketType::JOIN_REQUEST: + case SerialPacketType::JOIN_RESPONSE: + case SerialPacketType::SYNCHRONIZE: + case SerialPacketType::DISCONNECT: + case SerialPacketType::SHUTDOWN: + deserializeClient(dynamic_cast(packet), buffer); + break; + + //combat info + case SerialPacketType::COMBAT_NEW: + case SerialPacketType::COMBAT_DELETE: + case SerialPacketType::COMBAT_UPDATE: + + //TODO: is this the best fit? + case SerialPacketType::COMBAT_ENTER_REQUEST: + case SerialPacketType::COMBAT_ENTER_RESPONSE: + case SerialPacketType::COMBAT_EXIT_REQUEST: + case SerialPacketType::COMBAT_EXIT_RESPONSE: + + serializeCombat(dynamic_cast(packet), buffer); + break; + + //enemy info + case SerialPacketType::ENEMY_NEW: + case SerialPacketType::ENEMY_DELETE: + case SerialPacketType::ENEMY_UPDATE: + case SerialPacketType::ENEMY_STATS_REQUEST: + case SerialPacketType::ENEMY_STATS_RESPONSE: + serializeEnemy(dynamic_cast(packet), buffer); + break; + + //region info + case SerialPacketType::REGION_REQUEST: + deserializeRegionFormat(dynamic_cast(packet), buffer); + break; + + case SerialPacketType::REGION_CONTENT: + deserializeRegionContent(dynamic_cast(packet), buffer); + break; + + //server info + case SerialPacketType::BROADCAST_RESPONSE: + deserializeServer(dynamic_cast(packet), buffer); + break; + } +} \ No newline at end of file diff --git a/common/network/serial/serial.hpp b/common/network/serial/serial.hpp new file mode 100644 index 0000000..02d5dba --- /dev/null +++ b/common/network/serial/serial.hpp @@ -0,0 +1,65 @@ +/* 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 SERIALIZE_HPP_ +#define SERIALIZE_HPP_ + +#include "serial_packet.hpp" + +#include "region.hpp" +#include "statistics.hpp" + +//Primary interface functions +void serializePacket(SerialPacketBase*, void* dest); +void deserializePacket(SerialPacketBase*, void* src); + +void serializeType(SerialPacketBase*, void*); +void deserializeType(SerialPacketBase*, void*); + +//utility functions, exposed +void serializeCharacter(CharacterPacket*, void*); +void serializeClient(ClientPacket*, void*); +void serializeCombat(CombatPacket*, void*); +void serializeEnemy(EnemyPacket*, void*); +void serializeRegionFormat(RegionPacket*, void*); +void serializeRegionContent(RegionPacket*, void*); +void serializeServer(ServerPacket*, void*); +void serializeStatistics(Statistics*, void*); + +void deserializeCharacter(CharacterPacket*, void*); +void deserializeClient(ClientPacket*, void*); +void deserializeCombat(CombatPacket*, void*); +void deserializeEnemy(EnemyPacket*, void*); +void deserializeRegionFormat(RegionPacket*, void*); +void deserializeRegionContent(RegionPacket*, void*); +void deserializeServer(ServerPacket*, void*); +void deserializeStatistics(Statistics*, void*); + +/* DOCS: Keep the PACKET_BUFFER_SIZE up to date + * DOCS: REGION_CONTENT is currently the largest type of packet, read more + * map content: REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizoeof(region::type_t) + * map format: sizeof(int) * 3 + * metadata: sizeof(SerialPacket::Type) +*/ + +constexpr int PACKET_BUFFER_SIZE = REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 3 + sizeof(SerialPacketType); + +#endif \ No newline at end of file diff --git a/common/network/serial/serial_character.cpp b/common/network/serial/serial_character.cpp new file mode 100644 index 0000000..033944a --- /dev/null +++ b/common/network/serial/serial_character.cpp @@ -0,0 +1,44 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +void serializeCharacter(CharacterPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO + + //stats structure + serializeStatistics(&packet->stats, buffer); + buffer = reinterpret_cast(buffer) + sizeof(Statistics); +} + +void deserializeCharacter(CharacterPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO + + //stats structure + deserializeStatistics(&packet->stats, buffer); + buffer = reinterpret_cast(buffer) + sizeof(Statistics); +} diff --git a/common/network/serial/serial_client.cpp b/common/network/serial/serial_client.cpp new file mode 100644 index 0000000..4a818cf --- /dev/null +++ b/common/network/serial/serial_client.cpp @@ -0,0 +1,36 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +void serializeClient(ClientPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO +} + +void deserializeClient(ClientPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO +} diff --git a/common/network/serial/serial_combat.cpp b/common/network/serial/serial_combat.cpp new file mode 100644 index 0000000..6fbb053 --- /dev/null +++ b/common/network/serial/serial_combat.cpp @@ -0,0 +1,36 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +void serializeCombat(CombatPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO +} + +void deserializeCombat(CombatPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO +} diff --git a/common/network/serial/serial_enemy.cpp b/common/network/serial/serial_enemy.cpp new file mode 100644 index 0000000..4059ea5 --- /dev/null +++ b/common/network/serial/serial_enemy.cpp @@ -0,0 +1,44 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +void serializeEnemy(EnemyPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO + + //stats structure + serializeStatistics(&packet->stats, buffer); + buffer = reinterpret_cast(buffer) + sizeof(Statistics); +} + +void deserializeEnemy(EnemyPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO + + //stats structure + deserializeStatistics(&packet->stats, buffer); + buffer = reinterpret_cast(buffer) + sizeof(Statistics); +} diff --git a/common/network/serial/serial_region.cpp b/common/network/serial/serial_region.cpp new file mode 100644 index 0000000..e0860ac --- /dev/null +++ b/common/network/serial/serial_region.cpp @@ -0,0 +1,89 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +#include "map_allocator.hpp" + +void serializeRegionFormat(RegionPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //format + SERIALIZE(buffer, &packet->roomIndex, sizeof(int)); + SERIALIZE(buffer, &packet->x, sizeof(int)); + SERIALIZE(buffer, &packet->y, sizeof(int)); +} + +void serializeRegionContent(RegionPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //format + SERIALIZE(buffer, &packet->roomIndex, sizeof(int)); + SERIALIZE(buffer, &packet->x, sizeof(int)); + SERIALIZE(buffer, &packet->y, sizeof(int)); + + //content + for (register int i = 0; i < REGION_WIDTH; i++) { + for (register int j = 0; j < REGION_HEIGHT; j++) { + for (register int k = 0; k < REGION_DEPTH; k++) { + *reinterpret_cast(buffer) = packet->region->GetTile(i, j, k); + buffer = reinterpret_cast(buffer) + sizeof(Region::type_t); + } + } + } +} + +void deserializeRegionFormat(RegionPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //format + DESERIALIZE(buffer, &packet->roomIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->x, sizeof(int)); + DESERIALIZE(buffer, &packet->y, sizeof(int)); +} + +void deserializeRegionContent(RegionPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //format + DESERIALIZE(buffer, &packet->roomIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->x, sizeof(int)); + DESERIALIZE(buffer, &packet->y, sizeof(int)); + + //an object to work on + BlankAllocator().Create( + &packet->region, + packet->x, + packet->y + ); + + //content + for (register int i = 0; i < REGION_WIDTH; i++) { + for (register int j = 0; j < REGION_HEIGHT; j++) { + for (register int k = 0; k < REGION_DEPTH; k++) { + packet->region->SetTile(i, j, k, *reinterpret_cast(buffer)); + buffer = reinterpret_cast(buffer) + sizeof(Region::type_t); + } + } + } +} \ No newline at end of file diff --git a/common/network/serial/serial_server.cpp b/common/network/serial/serial_server.cpp new file mode 100644 index 0000000..1f94dd4 --- /dev/null +++ b/common/network/serial/serial_server.cpp @@ -0,0 +1,36 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +void serializeServer(ServerPacket* packet, void* buffer) { + SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO +} + +void deserializeServer(ServerPacket* packet, void* buffer) { + DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); + + //TODO +} diff --git a/common/network/serial/serial_statistics.cpp b/common/network/serial/serial_statistics.cpp new file mode 100644 index 0000000..6a594a8 --- /dev/null +++ b/common/network/serial/serial_statistics.cpp @@ -0,0 +1,65 @@ +/* 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 "serial.hpp" + +#include "serial_util.hpp" + +void serializeStatistics(Statistics* stats, void* buffer) { + //integers + SERIALIZE(buffer, &stats->level, sizeof(int)); + SERIALIZE(buffer, &stats->exp, sizeof(int)); + SERIALIZE(buffer, &stats->maxHP, sizeof(int)); + SERIALIZE(buffer, &stats->health, sizeof(int)); + SERIALIZE(buffer, &stats->maxMP, sizeof(int)); + SERIALIZE(buffer, &stats->mana, sizeof(int)); + SERIALIZE(buffer, &stats->attack, sizeof(int)); + SERIALIZE(buffer, &stats->defence, sizeof(int)); + SERIALIZE(buffer, &stats->intelligence, sizeof(int)); + SERIALIZE(buffer, &stats->resistance, sizeof(int)); + SERIALIZE(buffer, &stats->speed, sizeof(int)); + + //floats + SERIALIZE(buffer, &stats->accuracy, sizeof(float)); + SERIALIZE(buffer, &stats->evasion, sizeof(float)); + SERIALIZE(buffer, &stats->luck, sizeof(float)); +} + + +void deserializeStatistics(Statistics* stats, void* buffer) { + //integers + DESERIALIZE(buffer, &stats->level, sizeof(int)); + DESERIALIZE(buffer, &stats->exp, sizeof(int)); + DESERIALIZE(buffer, &stats->maxHP, sizeof(int)); + DESERIALIZE(buffer, &stats->health, sizeof(int)); + DESERIALIZE(buffer, &stats->maxMP, sizeof(int)); + DESERIALIZE(buffer, &stats->mana, sizeof(int)); + DESERIALIZE(buffer, &stats->attack, sizeof(int)); + DESERIALIZE(buffer, &stats->defence, sizeof(int)); + DESERIALIZE(buffer, &stats->intelligence, sizeof(int)); + DESERIALIZE(buffer, &stats->resistance, sizeof(int)); + DESERIALIZE(buffer, &stats->speed, sizeof(int)); + + //floats + DESERIALIZE(buffer, &stats->accuracy, sizeof(float)); + DESERIALIZE(buffer, &stats->evasion, sizeof(float)); + DESERIALIZE(buffer, &stats->luck, sizeof(float)); +} diff --git a/common/network/serial.hpp b/common/network/serial/serial_util.hpp similarity index 60% rename from common/network/serial.hpp rename to common/network/serial/serial_util.hpp index 29b9c2d..a0910b8 100644 --- a/common/network/serial.hpp +++ b/common/network/serial/serial_util.hpp @@ -19,20 +19,13 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef SERIAL_HPP_ -#define SERIAL_HPP_ +#ifndef SERIALIZEUTIL_HPP_ +#define SERIALIZEUTIL_HPP_ -#include "serial_packet.hpp" +#include -/* NOTE: Keep the PACKET_BUFFER_SIZE up to date - * NOTE: REGION_CONTENT is currently the largest type of packet - * map content: REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizoeof(region::type_t) - * map format: sizeof(int) * 3 - * metadata: sizeof(SerialPacket::Type) -*/ -#define PACKET_BUFFER_SIZE REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 3 + sizeof(SerialPacket::Type) - -void serialize(SerialPacket* const, void* dest); -void deserialize(SerialPacket* const, void* src); +//NOTE: The strange assignments here used in order to move the void* parameter +#define SERIALIZE(buffer, data, size) memcpy(buffer, data, size); buffer = reinterpret_cast(buffer) + size; +#define DESERIALIZE(buffer, data, size) memcpy(data, buffer, size); buffer = reinterpret_cast(buffer) + size; #endif From 46dff9b97bb276947e60f9c238298c1d797d6cd0 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 4 Jun 2014 23:08:52 +1000 Subject: [PATCH 03/34] Implemented the minor changes into UDPNetworkPacket --- common/network/makefile | 4 +++- common/network/udp_network_utility.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/common/network/makefile b/common/network/makefile index 7053c0f..618d925 100644 --- a/common/network/makefile +++ b/common/network/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../gameplay ../map ../utilities +INCLUDES+=. packet serial ../gameplay ../map ../utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) @@ -17,6 +17,8 @@ OUT=$(addprefix $(OUTDIR)/,libcommon.a) #targets all: $(OBJ) $(OUT) ar -crs $(OUT) $(OBJ) + $(MAKE) -C packet + $(MAKE) -C serial $(OBJ): | $(OBJDIR) diff --git a/common/network/udp_network_utility.cpp b/common/network/udp_network_utility.cpp index 5fb669e..275c1c8 100644 --- a/common/network/udp_network_utility.cpp +++ b/common/network/udp_network_utility.cpp @@ -166,7 +166,7 @@ int UDPNetworkUtility::SendTo(const char* ip, int port, SerialPacket* serialPack int UDPNetworkUtility::SendTo(IPaddress* add, SerialPacket* serialPacket) { memset(packet->data, 0, packet->maxlen); - serialize(serialPacket, packet->data); + serializePacket(serialPacket, packet->data); packet->len = PACKET_BUFFER_SIZE; packet->address = *add; @@ -181,7 +181,7 @@ int UDPNetworkUtility::SendTo(IPaddress* add, SerialPacket* serialPacket) { int UDPNetworkUtility::SendTo(int channel, SerialPacket* serialPacket) { memset(packet->data, 0, packet->maxlen); - serialize(serialPacket, packet->data); + serializePacket(serialPacket, packet->data); packet->len = PACKET_BUFFER_SIZE; int ret = SDLNet_UDP_Send(socket, channel, packet); @@ -195,7 +195,7 @@ int UDPNetworkUtility::SendTo(int channel, SerialPacket* serialPacket) { int UDPNetworkUtility::SendToAllChannels(SerialPacket* serialPacket) { memset(packet->data, 0, packet->maxlen); - serialize(serialPacket, packet->data); + serializePacket(serialPacket, packet->data); packet->len = PACKET_BUFFER_SIZE; int sent = 0; @@ -213,8 +213,8 @@ int UDPNetworkUtility::SendToAllChannels(SerialPacket* serialPacket) { int UDPNetworkUtility::Receive(SerialPacket* serialPacket) { memset(packet->data, 0, packet->maxlen); int ret = SDLNet_UDP_Recv(socket, packet); - deserialize(serialPacket, packet->data); - serialPacket->meta.srcAddress = packet->address; + deserializePacket(serialPacket, packet->data); + serialPacket->srcAddress = packet->address; if (ret < 0) { throw(std::runtime_error("Unknown network error occured")); From 5966d7b51ab083df9b35277d2467ec0595d4e743 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 4 Jun 2014 23:30:20 +1000 Subject: [PATCH 04/34] Fleshed out the serialization internals --- common/gameplay/enemy_data.hpp | 2 ++ common/network/packet/enemy_packet.hpp | 5 +++ common/network/serial/serial_character.cpp | 40 ++++++++++++++++++++-- common/network/serial/serial_client.cpp | 10 ++++-- common/network/serial/serial_combat.cpp | 32 +++++++++++++++-- common/network/serial/serial_enemy.cpp | 26 ++++++++++++-- common/network/serial/serial_server.cpp | 10 ++++-- 7 files changed, 115 insertions(+), 10 deletions(-) diff --git a/common/gameplay/enemy_data.hpp b/common/gameplay/enemy_data.hpp index 62de98c..9fd96e2 100644 --- a/common/gameplay/enemy_data.hpp +++ b/common/gameplay/enemy_data.hpp @@ -46,6 +46,8 @@ struct EnemyData { //TODO: buffs //TODO: debuffs + //TODO: rewards + //active gameplay members //NOTE: these are lost when unloaded #ifdef GRAPHICS diff --git a/common/network/packet/enemy_packet.hpp b/common/network/packet/enemy_packet.hpp index bbe68c9..4a3d343 100644 --- a/common/network/packet/enemy_packet.hpp +++ b/common/network/packet/enemy_packet.hpp @@ -33,6 +33,11 @@ struct EnemyPacket : SerialPacketBase { //gameplay Statistics stats; + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs + //TODO: rewards }; diff --git a/common/network/serial/serial_character.cpp b/common/network/serial/serial_character.cpp index 033944a..3805702 100644 --- a/common/network/serial/serial_character.cpp +++ b/common/network/serial/serial_character.cpp @@ -26,19 +26,55 @@ void serializeCharacter(CharacterPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the character + SERIALIZE(buffer, &packet->characterIndex, sizeof(int)); + SERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE); + SERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE); + + //the owner + SERIALIZE(buffer, &packet->accountIndex, sizeof(int)); + + //location + SERIALIZE(buffer, &packet->roomIndex, sizeof(int)); + SERIALIZE(buffer, &packet->origin.x, sizeof(double)); + SERIALIZE(buffer, &packet->origin.y, sizeof(double)); + SERIALIZE(buffer, &packet->motion.x, sizeof(double)); + SERIALIZE(buffer, &packet->motion.y, sizeof(double)); //stats structure serializeStatistics(&packet->stats, buffer); buffer = reinterpret_cast(buffer) + sizeof(Statistics); + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs } void deserializeCharacter(CharacterPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the character + DESERIALIZE(buffer, &packet->characterIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE); + DESERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE); + + //the owner + DESERIALIZE(buffer, &packet->accountIndex, sizeof(int)); + + //location + DESERIALIZE(buffer, &packet->roomIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->origin.x, sizeof(double)); + DESERIALIZE(buffer, &packet->origin.y, sizeof(double)); + DESERIALIZE(buffer, &packet->motion.x, sizeof(double)); + DESERIALIZE(buffer, &packet->motion.y, sizeof(double)); //stats structure deserializeStatistics(&packet->stats, buffer); buffer = reinterpret_cast(buffer) + sizeof(Statistics); + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs } diff --git a/common/network/serial/serial_client.cpp b/common/network/serial/serial_client.cpp index 4a818cf..bbc07b9 100644 --- a/common/network/serial/serial_client.cpp +++ b/common/network/serial/serial_client.cpp @@ -26,11 +26,17 @@ void serializeClient(ClientPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + SERIALIZE(buffer, &packet->clientIndex, sizeof(int)); + SERIALIZE(buffer, &packet->accountIndex, sizeof(int)); + SERIALIZE(buffer, &packet->username, sizeof(PACKET_STRING_SIZE)); + SERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); } void deserializeClient(ClientPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + DESERIALIZE(buffer, &packet->clientIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->accountIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->username, sizeof(PACKET_STRING_SIZE)); + DESERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); } diff --git a/common/network/serial/serial_combat.cpp b/common/network/serial/serial_combat.cpp index 6fbb053..881db97 100644 --- a/common/network/serial/serial_combat.cpp +++ b/common/network/serial/serial_combat.cpp @@ -26,11 +26,39 @@ void serializeCombat(CombatPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the combat instance + SERIALIZE(buffer, &packet->combatIndex, sizeof(int)); + SERIALIZE(buffer, &packet->difficulty, sizeof(int)); + SERIALIZE(buffer, &packet->terrainType, sizeof(CombatData::Terrain)); + + //combatants + SERIALIZE(buffer, &packet->characterArray, sizeof(int) * COMBAT_MAX_CHARACTERS); + SERIALIZE(buffer, &packet->enemyArray, sizeof(int) * COMBAT_MAX_ENEMIES); + + //location + SERIALIZE(buffer, &packet->mapIndex, sizeof(int)); + SERIALIZE(buffer, &packet->origin.x, sizeof(double)); + SERIALIZE(buffer, &packet->origin.y, sizeof(double)); + + //TODO: rewards } void deserializeCombat(CombatPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the combat instance + DESERIALIZE(buffer, &packet->combatIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->difficulty, sizeof(int)); + DESERIALIZE(buffer, &packet->terrainType, sizeof(CombatData::Terrain)); + + //combatants + DESERIALIZE(buffer, &packet->characterArray, sizeof(int) * COMBAT_MAX_CHARACTERS); + DESERIALIZE(buffer, &packet->enemyArray, sizeof(int) * COMBAT_MAX_ENEMIES); + + //location + DESERIALIZE(buffer, &packet->mapIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->origin.x, sizeof(double)); + DESERIALIZE(buffer, &packet->origin.y, sizeof(double)); + + //TODO: rewards } diff --git a/common/network/serial/serial_enemy.cpp b/common/network/serial/serial_enemy.cpp index 4059ea5..363ca1f 100644 --- a/common/network/serial/serial_enemy.cpp +++ b/common/network/serial/serial_enemy.cpp @@ -26,19 +26,41 @@ void serializeEnemy(EnemyPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the enemy + SERIALIZE(buffer, &packet->enemyIndex, sizeof(int)); + SERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE); + SERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE); + + //gameplay //stats structure serializeStatistics(&packet->stats, buffer); buffer = reinterpret_cast(buffer) + sizeof(Statistics); + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs + + //TODO: rewards } void deserializeEnemy(EnemyPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the enemy + DESERIALIZE(buffer, &packet->enemyIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE); + DESERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE); //stats structure deserializeStatistics(&packet->stats, buffer); buffer = reinterpret_cast(buffer) + sizeof(Statistics); + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs + + //TODO: rewards } diff --git a/common/network/serial/serial_server.cpp b/common/network/serial/serial_server.cpp index 1f94dd4..12a2f34 100644 --- a/common/network/serial/serial_server.cpp +++ b/common/network/serial/serial_server.cpp @@ -26,11 +26,17 @@ void serializeServer(ServerPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the server + SERIALIZE(buffer, &packet->name, PACKET_STRING_SIZE); + SERIALIZE(buffer, &packet->playerCount, sizeof(int)); + SERIALIZE(buffer, &packet->version, sizeof(int)); } void deserializeServer(ServerPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); - //TODO + //identify the server + DESERIALIZE(buffer, &packet->name, PACKET_STRING_SIZE); + DESERIALIZE(buffer, &packet->playerCount, sizeof(int)); + DESERIALIZE(buffer, &packet->version, sizeof(int)); } From 2c9b0fc3e76bee67466cefc87da46c74317ce9f9 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 21:12:46 +1000 Subject: [PATCH 05/34] Committing some comment tweaks --- client/in_combat.cpp | 2 +- client/in_world.cpp | 2 +- client/lobby_menu.cpp | 2 +- common/network/packet/client_packet.hpp | 2 +- common/network/packet/serial_packet_type.hpp | 27 +++++++++++++++----- common/network/serial/serial.cpp | 4 --- common/network/serial/serial_client.cpp | 4 +-- server/server_internals.cpp | 2 +- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/client/in_combat.cpp b/client/in_combat.cpp index 6be762f..207b97e 100644 --- a/client/in_combat.cpp +++ b/client/in_combat.cpp @@ -161,7 +161,7 @@ void InCombat::HandlePacket(SerialPacket packet) { break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in InCombat: " + to_string_custom(int(packet.meta.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InCombat: " + to_string_custom(int(packet.meta.type)))); break; } } diff --git a/client/in_world.cpp b/client/in_world.cpp index 01a8ed0..6aa6a5a 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -267,7 +267,7 @@ void InWorld::HandlePacket(SerialPacket packet) { break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in InWorld: " + to_string_custom(int(packet.meta.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(int(packet.meta.type)))); break; } } diff --git a/client/lobby_menu.cpp b/client/lobby_menu.cpp index fa1925e..ddc6998 100644 --- a/client/lobby_menu.cpp +++ b/client/lobby_menu.cpp @@ -231,7 +231,7 @@ void LobbyMenu::HandlePacket(SerialPacket packet) { //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in LobbyMenu: " + to_string_custom(int(packet.meta.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(int(packet.meta.type)))); break; } } \ No newline at end of file diff --git a/common/network/packet/client_packet.hpp b/common/network/packet/client_packet.hpp index 995bc4a..f191b11 100644 --- a/common/network/packet/client_packet.hpp +++ b/common/network/packet/client_packet.hpp @@ -28,7 +28,7 @@ struct ClientPacket : SerialPacketBase { int clientIndex; int accountIndex; char username[PACKET_STRING_SIZE]; - char password[PACKET_STRING_SIZE]; //hashed, not currently used +// char password[PACKET_STRING_SIZE]; //hashed, not currently used }; #endif \ No newline at end of file diff --git a/common/network/packet/serial_packet_type.hpp b/common/network/packet/serial_packet_type.hpp index 8fbcd17..dceffaa 100644 --- a/common/network/packet/serial_packet_type.hpp +++ b/common/network/packet/serial_packet_type.hpp @@ -22,39 +22,49 @@ #ifndef SERIALPACKETTYPE_HPP_ #define SERIALPACKETTYPE_HPP_ +/* Key for the comments: + * request => response +*/ + enum class SerialPacketType { //default: there is something wrong NONE = 0, //keep alive + //ping => pong PING, PONG, - //searching for a server to join + //search for the server list + //none => server name, player count, version info (and source address) BROADCAST_REQUEST, BROADCAST_RESPONSE, - BROADCAST_REJECTION, //try to join the server + //username, and password => client index, account index JOIN_REQUEST, JOIN_RESPONSE, JOIN_REJECTION, - //mass update + //mass update of all surrounding content + //character.x, character.y => packet barrage SYNCHRONIZE, //disconnect from the server + //autentication, account index => disconnect that account DISCONNECT, //shut down the server + //autentication => disconnect, shutdown SHUTDOWN, //map data + //room index, region.x, region.y => room index, region.x, region.y, region content REGION_REQUEST, REGION_CONTENT, - REGION_REJECTION, //combat data + //TODO: system incomplete COMBAT_NEW, COMBAT_DELETE, COMBAT_UPDATE, @@ -70,16 +80,20 @@ enum class SerialPacketType { COMBAT_REJECTION, //character data + //character data => etc. CHARACTER_NEW, CHARACTER_DELETE, CHARACTER_UPDATE, + //authentication, character index => character stats CHARACTER_STATS_REQUEST, CHARACTER_STATS_RESPONSE, + //character new => character rejection, disconnect? CHARACTER_REJECTION, //enemy data + //enemy data => etc. ENEMY_NEW, ENEMY_DELETE, ENEMY_UPDATE, @@ -87,12 +101,13 @@ enum class SerialPacketType { ENEMY_STATS_REQUEST, ENEMY_STATS_RESPONSE, + //enemy index => enemy doens't exist ENEMY_REJECTION, - //more packet types go here + //NOTE: more packet types go here //not used - LAST, + LAST }; #endif \ No newline at end of file diff --git a/common/network/serial/serial.cpp b/common/network/serial/serial.cpp index c73b2bc..423f6c1 100644 --- a/common/network/serial/serial.cpp +++ b/common/network/serial/serial.cpp @@ -42,9 +42,7 @@ void serializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::BROADCAST_REQUEST: //all rejections - case SerialPacketType::BROADCAST_REJECTION: case SerialPacketType::JOIN_REJECTION: - case SerialPacketType::REGION_REJECTION: case SerialPacketType::CHARACTER_REJECTION: case SerialPacketType::ENEMY_REJECTION: case SerialPacketType::COMBAT_REJECTION: @@ -120,9 +118,7 @@ void deserializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::BROADCAST_REQUEST: //all rejections - case SerialPacketType::BROADCAST_REJECTION: case SerialPacketType::JOIN_REJECTION: - case SerialPacketType::REGION_REJECTION: case SerialPacketType::CHARACTER_REJECTION: case SerialPacketType::ENEMY_REJECTION: case SerialPacketType::COMBAT_REJECTION: diff --git a/common/network/serial/serial_client.cpp b/common/network/serial/serial_client.cpp index bbc07b9..c96449d 100644 --- a/common/network/serial/serial_client.cpp +++ b/common/network/serial/serial_client.cpp @@ -29,7 +29,7 @@ void serializeClient(ClientPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->clientIndex, sizeof(int)); SERIALIZE(buffer, &packet->accountIndex, sizeof(int)); SERIALIZE(buffer, &packet->username, sizeof(PACKET_STRING_SIZE)); - SERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); +// SERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); } void deserializeClient(ClientPacket* packet, void* buffer) { @@ -38,5 +38,5 @@ void deserializeClient(ClientPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->clientIndex, sizeof(int)); DESERIALIZE(buffer, &packet->accountIndex, sizeof(int)); DESERIALIZE(buffer, &packet->username, sizeof(PACKET_STRING_SIZE)); - DESERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); +// DESERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); } diff --git a/server/server_internals.cpp b/server/server_internals.cpp index 4ee835f..c5298fc 100644 --- a/server/server_internals.cpp +++ b/server/server_internals.cpp @@ -184,7 +184,7 @@ void ServerApplication::HandlePacket(SerialPacket packet) { break; //handle errors default: - throw(std::runtime_error("Unknown SerialPacket::Type encountered")); + throw(std::runtime_error("Unknown SerialPacketType encountered")); break; } } From 6664f8a8bcce2042be42da724088e7307796eb99 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 21:14:41 +1000 Subject: [PATCH 06/34] Renamed server_connections.cpp => network_handlers.cpp --- server/{server_connections.cpp => network_handlers.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename server/{server_connections.cpp => network_handlers.cpp} (100%) diff --git a/server/server_connections.cpp b/server/network_handlers.cpp similarity index 100% rename from server/server_connections.cpp rename to server/network_handlers.cpp From 310f701b0decae994ea3651f66448095b90f598b Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 21:42:27 +1000 Subject: [PATCH 07/34] Began modulating ServerApplication, beginning with the accounts --- common/gameplay/sanity_check.cpp | 1 - {common/gameplay => server}/account_data.hpp | 0 ...unt_management.cpp => account_manager.cpp} | 42 +++++++++++--- server/account_manager.hpp | 55 +++++++++++++++++++ server/server_application.hpp | 8 +-- 5 files changed, 89 insertions(+), 17 deletions(-) rename {common/gameplay => server}/account_data.hpp (100%) rename server/{account_management.cpp => account_manager.cpp} (88%) create mode 100644 server/account_manager.hpp diff --git a/common/gameplay/sanity_check.cpp b/common/gameplay/sanity_check.cpp index 719db9f..22f1737 100644 --- a/common/gameplay/sanity_check.cpp +++ b/common/gameplay/sanity_check.cpp @@ -19,7 +19,6 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "account_data.hpp" #include "character_data.hpp" #include "client_data.hpp" #include "combat_data.hpp" diff --git a/common/gameplay/account_data.hpp b/server/account_data.hpp similarity index 100% rename from common/gameplay/account_data.hpp rename to server/account_data.hpp diff --git a/server/account_management.cpp b/server/account_manager.cpp similarity index 88% rename from server/account_management.cpp rename to server/account_manager.cpp index eb298d8..424c125 100644 --- a/server/account_management.cpp +++ b/server/account_manager.cpp @@ -19,9 +19,7 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "server_application.hpp" - -#include "sqlite3/sqlite3.h" +#include "account_manager.hpp" #include @@ -35,10 +33,10 @@ static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET blacklisted static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;"; //------------------------- -//Define the methods +//Define the public methods //------------------------- -int ServerApplication::CreateUserAccount(std::string username, int clientIndex) { +int AccountManager::CreateUserAccount(std::string username, int clientIndex) { //create this user account, failing if it exists, leave this account in memory sqlite3_stmt* statement = nullptr; @@ -65,7 +63,7 @@ int ServerApplication::CreateUserAccount(std::string username, int clientIndex) return LoadUserAccount(username, clientIndex); } -int ServerApplication::LoadUserAccount(std::string username, int clientIndex) { +int AccountManager::LoadUserAccount(std::string username, int clientIndex) { //load this user account, failing if it is in memory, creating it if it doesn't exist sqlite3_stmt* statement = nullptr; @@ -117,7 +115,7 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex) { throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) )); } -int ServerApplication::SaveUserAccount(int uid) { +int AccountManager::SaveUserAccount(int uid) { //save this user account from memory, replacing it if it exists in the database //DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID. @@ -160,14 +158,14 @@ int ServerApplication::SaveUserAccount(int uid) { return 0; } -void ServerApplication::UnloadUserAccount(int uid) { +void AccountManager::UnloadUserAccount(int uid) { //save this user account, and then unload it //NOTE: the associated characters are unloaded externally SaveUserAccount(uid); accountMap.erase(uid); } -void ServerApplication::DeleteUserAccount(int uid) { +void AccountManager::DeleteUserAccount(int uid) { //delete a user account from the database, and remove it from memory //NOTE: the associated characters should be deleted externally sqlite3_stmt* statement = nullptr; @@ -193,3 +191,29 @@ void ServerApplication::DeleteUserAccount(int uid) { sqlite3_finalize(statement); accountMap.erase(uid); } + +//------------------------- +//Define the accessors and mutators +//------------------------- + +AccountData* AccountManager::GetAccount(int uid) { + std::map::iterator it = accountMap.find(uid); + + if (it == accountMap.end()) { + return nullptr; + } + + return &it->second; +} + +std::map* AccountManager::GetContainer() { + return &accountMap; +} + +sqlite3* AccountManager::SetDatabase(sqlite3* db) { + return database = db; +} + +sqlite3* AccountManager::GetDatabase() { + return database; +} \ No newline at end of file diff --git a/server/account_manager.hpp b/server/account_manager.hpp new file mode 100644 index 0000000..6d109ac --- /dev/null +++ b/server/account_manager.hpp @@ -0,0 +1,55 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef ACCOUNTMANAGER_HPP_ +#define ACCOUNTMANAGER_HPP_ + +#include "account_data.hpp" + +#include "sqlite3/sqlite3.h" + +#include + +class AccountManager { +public: + AccountManager() = default; + ~AccountManager() = default; + + //public access methods + int CreateUserAccount(std::string username, int clientIndex); + int LoadUserAccount(std::string username, int clientIndex); + int SaveUserAccount(int uid); + void UnloadUserAccount(int uid); + void DeleteUserAccount(int uid); + + //accessors and mutators + AccountData* GetAccount(int uid); + std::map* GetContainer(); + + sqlite3* SetDatabase(sqlite3* db); + sqlite3* GetDatabase(); + +private: + std::map accountMap; + sqlite3* database = nullptr; +}; + +#endif diff --git a/server/server_application.hpp b/server/server_application.hpp index cbc7511..87f34de 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -79,12 +79,7 @@ private: void PumpCharacterUnload(int uid); //Account management - int CreateUserAccount(std::string username, int clientIndex); - int LoadUserAccount(std::string username, int clientIndex); - int SaveUserAccount(int uid); - void UnloadUserAccount(int uid); - void DeleteUserAccount(int uid); - + //character management int CreateCharacter(int owner, std::string handle, std::string avatar); int LoadCharacter(int owner, std::string handle, std::string avatar); @@ -101,7 +96,6 @@ private: //server tables std::map clientMap; - std::map accountMap; std::map characterMap; std::map combatMap; std::map enemyMap; From 7fb458ddc14a16fbe10a09e13a09572991f8104c Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 21:52:22 +1000 Subject: [PATCH 08/34] Refactored the character management into a separate class --- ...r_management.cpp => character_manager.cpp} | 38 +++++++++++-- server/character_manager.hpp | 55 +++++++++++++++++++ server/server_application.hpp | 5 -- 3 files changed, 87 insertions(+), 11 deletions(-) rename server/{character_management.cpp => character_manager.cpp} (91%) create mode 100644 server/character_manager.hpp diff --git a/server/character_management.cpp b/server/character_manager.cpp similarity index 91% rename from server/character_management.cpp rename to server/character_manager.cpp index 3991305..4064f5d 100644 --- a/server/character_management.cpp +++ b/server/character_manager.cpp @@ -19,7 +19,7 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "server_application.hpp" +#include "character_manager.hpp" #include "sqlite3/sqlite3.h" @@ -60,7 +60,7 @@ static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; //TODO: should statistics be stored separately? //TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes -int ServerApplication::CreateCharacter(int owner, std::string handle, std::string avatar) { +int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) { //Create the character, failing if it exists sqlite3_stmt* statement = nullptr; @@ -93,7 +93,7 @@ int ServerApplication::CreateCharacter(int owner, std::string handle, std::strin return LoadCharacter(owner, handle, avatar); } -int ServerApplication::LoadCharacter(int owner, std::string handle, std::string avatar) { +int CharacterManager::LoadCharacter(int owner, std::string handle, std::string avatar) { //load the specified character, creating it if it doesn't exist //fail if it is already loaded, or does not belong to this account sqlite3_stmt* statement = nullptr; @@ -178,7 +178,7 @@ int ServerApplication::LoadCharacter(int owner, std::string handle, std::string throw(std::runtime_error(std::string() + "Unknown SQL error in LoadCharacter: " + sqlite3_errmsg(database) )); } -int ServerApplication::SaveCharacter(int uid) { +int CharacterManager::SaveCharacter(int uid) { //save this character from memory, replacing it if it exists in the database //DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID. @@ -241,13 +241,13 @@ int ServerApplication::SaveCharacter(int uid) { return 0; } -void ServerApplication::UnloadCharacter(int uid) { +void CharacterManager::UnloadCharacter(int uid) { //save this character, then unload it SaveCharacter(uid); characterMap.erase(uid); } -void ServerApplication::DeleteCharacter(int uid) { +void CharacterManager::DeleteCharacter(int uid) { //delete this character from the database, then remove it from memory sqlite3_stmt* statement = nullptr; @@ -272,3 +272,29 @@ void ServerApplication::DeleteCharacter(int uid) { sqlite3_finalize(statement); characterMap.erase(uid); } + +//------------------------- +//Define the accessors and mutators +//------------------------- + +CharacterData* CharacterManager::GetCharacter(int uid) { + std::map::iterator it = characterMap.find(uid); + + if (it == characterMap.end()) { + return nullptr; + } + + return &it->second; +} + +std::map* CharacterManager::GetContainer() { + return &characterMap; +} + +sqlite3* CharacterManager::SetDatabase(sqlite3* db) { + return database = db; +} + +sqlite3* CharacterManager::GetDatabase() { + return database; +} \ No newline at end of file diff --git a/server/character_manager.hpp b/server/character_manager.hpp new file mode 100644 index 0000000..c334a7a --- /dev/null +++ b/server/character_manager.hpp @@ -0,0 +1,55 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef CHARACTERMANAGER_HPP_ +#define CHARACTERMANAGER_HPP_ + +#include "character_data.hpp" + +#include "sqlite3/sqlite3.h" + +#include + +class CharacterManager { +public: + CharacterManager() = default; + ~CharacterManager() = default; + + //public access methods + int CreateCharacter(int owner, std::string handle, std::string avatar); + int LoadCharacter(int owner, std::string handle, std::string avatar); + int SaveCharacter(int uid); + void UnloadCharacter(int uid); + void DeleteCharacter(int uid); + + //accessors and mutators + CharacterData* GetCharacter(int uid); + std::map* GetContainer(); + + sqlite3* SetDatabase(sqlite3* db); + sqlite3* GetDatabase(); + +private: + std::map characterMap; + sqlite3* database = nullptr; +}; + +#endif diff --git a/server/server_application.hpp b/server/server_application.hpp index 87f34de..6016d8f 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -81,11 +81,6 @@ private: //Account management //character management - int CreateCharacter(int owner, std::string handle, std::string avatar); - int LoadCharacter(int owner, std::string handle, std::string avatar); - int SaveCharacter(int uid); - void UnloadCharacter(int uid); - void DeleteCharacter(int uid); //TODO: combat management From 973a2be16b1ebcd390b752a7b3a75941978b51be Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 22:11:05 +1000 Subject: [PATCH 09/34] Merged server_internals.cpp and network_handlers.cpp into server_application.cpp --- common/gameplay/sanity_check.cpp | 2 - {common/gameplay => server}/client_data.hpp | 0 {common/gameplay => server}/room_data.hpp | 0 ...rk_handlers.cpp => server_application.cpp} | 201 +++++++++++++++++- server/server_application.hpp | 7 +- server/server_internals.cpp | 190 ----------------- 6 files changed, 200 insertions(+), 200 deletions(-) rename {common/gameplay => server}/client_data.hpp (100%) rename {common/gameplay => server}/room_data.hpp (100%) rename server/{network_handlers.cpp => server_application.cpp} (56%) delete mode 100644 server/server_internals.cpp diff --git a/common/gameplay/sanity_check.cpp b/common/gameplay/sanity_check.cpp index 22f1737..8669811 100644 --- a/common/gameplay/sanity_check.cpp +++ b/common/gameplay/sanity_check.cpp @@ -20,10 +20,8 @@ * distribution. */ #include "character_data.hpp" -#include "client_data.hpp" #include "combat_data.hpp" #include "enemy_data.hpp" -#include "room_data.hpp" #include "statistics.hpp" /* DOCS: Sanity check, read more diff --git a/common/gameplay/client_data.hpp b/server/client_data.hpp similarity index 100% rename from common/gameplay/client_data.hpp rename to server/client_data.hpp diff --git a/common/gameplay/room_data.hpp b/server/room_data.hpp similarity index 100% rename from common/gameplay/room_data.hpp rename to server/room_data.hpp diff --git a/server/network_handlers.cpp b/server/server_application.cpp similarity index 56% rename from server/network_handlers.cpp rename to server/server_application.cpp index 047462f..8cd135f 100644 --- a/server/network_handlers.cpp +++ b/server/server_application.cpp @@ -1,4 +1,4 @@ -/* Copyright: (c) Kayne Ruse 2013, 2014 +/* 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 @@ -21,11 +21,199 @@ */ #include "server_application.hpp" +#include "sql_utility.hpp" +#include "serial.hpp" + #include #include +#include //------------------------- -//Handle various network input +//Define the public members +//------------------------- + +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 startup" << std::endl; + + //initial setup + 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 + //------------------------- + + //setup the map object + regionPager.GetAllocator()->SetLuaState(luaState); + regionPager.GetFormat()->SetLuaState(luaState); + regionPager.GetFormat()->SetSaveDir(config["dir.maps"] + config["map.savename"]); + std::cout << "Prepared the map system" << std::endl; + + //push the pager onto the lua registry + lua_pushstring(luaState, "pager"); + lua_pushlightuserdata(luaState, reinterpret_cast(®ionPager)); + lua_settable(luaState, LUA_REGISTRYINDEX); + std::cout << "Registered the map system in 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 + std::cout << "Internal sizes:" << std::endl; + std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl; + std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl; + + //finalize the startup + std::cout << "Startup completed successfully" << std::endl; + + //debugging + // +} + +void ServerApplication::Proc() { + SerialPacket packet; + while(running) { + //suck in the waiting packets & process them + while(network.Receive(&packet)) { + HandlePacket(packet); + } + //update the internals + //TODO: update the internals i.e. player positions + //give the computer a break + SDL_Delay(10); + } +} + +void ServerApplication::Quit() { + std::cout << "Shutting down" << std::endl; + + //save the server state + for (auto& it : accountMap) { + SaveUserAccount(it.first); + } + for (auto& it : characterMap) { + SaveCharacter(it.first); + } + + //empty the members + accountMap.clear(); + characterMap.clear(); + regionPager.UnloadAll(); + + //APIs + lua_close(luaState); + sqlite3_close_v2(database); + network.Close(); + SDLNet_Quit(); + SDL_Quit(); + + std::cout << "Shutdown finished" << std::endl; +} + +//------------------------- +//Define the network switch +//------------------------- + +void ServerApplication::HandlePacket(SerialPacket packet) { + switch(packet.meta.type) { + //basic connections + case SerialPacketType::BROADCAST_REQUEST: + HandleBroadcastRequest(packet); + break; + case SerialPacketType::JOIN_REQUEST: + HandleJoinRequest(packet); + break; + case SerialPacketType::DISCONNECT: + HandleDisconnect(packet); + break; + case SerialPacketType::SHUTDOWN: + HandleShutdown(packet); + break; + + //map management + case SerialPacketType::REGION_REQUEST: + HandleRegionRequest(packet); + break; + + //combat management + //TODO: combat management + + //character management + case SerialPacketType::CHARACTER_NEW: + HandleCharacterNew(packet); + break; + case SerialPacketType::CHARACTER_DELETE: + HandleCharacterDelete(packet); + break; + case SerialPacketType::CHARACTER_UPDATE: + HandleCharacterUpdate(packet); + break; + case SerialPacketType::CHARACTER_STATS_REQUEST: + HandleCharacterUpdate(packet); + break; + + //enemy management + //TODO: enemy management + + //mismanagement + case SerialPacketType::SYNCHRONIZE: + HandleSynchronize(packet); + break; + + //handle errors + default: + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(int(packet.type)))); + break; + } +} + +//------------------------- +//Define the network handlers //------------------------- void ServerApplication::HandleBroadcastRequest(SerialPacket packet) { @@ -191,4 +379,11 @@ void ServerApplication::PumpCharacterUnload(int uid) { delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; delPacket.characterInfo.characterIndex = uid; PumpPacket(delPacket); -} \ No newline at end of file +} + +//------------------------- +//Define the utility methods +//------------------------- + +//TODO: utility methods + diff --git a/server/server_application.hpp b/server/server_application.hpp index 6016d8f..3b24303 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -78,10 +78,8 @@ private: void PumpPacket(SerialPacket); void PumpCharacterUnload(int uid); - //Account management - - //character management - + //TODO: Account management + //TODO: character management //TODO: combat management //APIs @@ -91,7 +89,6 @@ private: //server tables std::map clientMap; - std::map characterMap; std::map combatMap; std::map enemyMap; diff --git a/server/server_internals.cpp b/server/server_internals.cpp deleted file mode 100644 index c5298fc..0000000 --- a/server/server_internals.cpp +++ /dev/null @@ -1,190 +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 "server_application.hpp" - -#include "sql_utility.hpp" -#include "serial.hpp" - -#include -#include -#include - -//------------------------- -//Define the public members -//------------------------- - -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 startup" << std::endl; - - //initial setup - 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 - //------------------------- - - //setup the map object - regionPager.GetAllocator()->SetLuaState(luaState); - regionPager.GetFormat()->SetLuaState(luaState); - regionPager.GetFormat()->SetSaveDir(config["dir.maps"] + config["map.savename"]); - std::cout << "Prepared the map system" << std::endl; - - //push the pager onto the lua registry - lua_pushstring(luaState, "pager"); - lua_pushlightuserdata(luaState, reinterpret_cast(®ionPager)); - lua_settable(luaState, LUA_REGISTRYINDEX); - std::cout << "Registered the map system in 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 - std::cout << "Internal sizes:" << std::endl; - std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl; - std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl; - - //finalize the startup - std::cout << "Startup completed successfully" << std::endl; - - //debugging - // -} - -void ServerApplication::Proc() { - SerialPacket packet; - while(running) { - //suck in the waiting packets & process them - while(network.Receive(&packet)) { - HandlePacket(packet); - } - //update the internals - //TODO: update the internals i.e. player positions - //give the computer a break - SDL_Delay(10); - } -} - -void ServerApplication::Quit() { - std::cout << "Shutting down" << std::endl; - - //save the server state - for (auto& it : accountMap) { - SaveUserAccount(it.first); - } - for (auto& it : characterMap) { - SaveCharacter(it.first); - } - - //empty the members - accountMap.clear(); - characterMap.clear(); - regionPager.UnloadAll(); - - //APIs - lua_close(luaState); - sqlite3_close_v2(database); - network.Close(); - SDLNet_Quit(); - SDL_Quit(); - - std::cout << "Shutdown finished" << std::endl; -} - -//------------------------- -//Define the uber switch -//------------------------- - -void ServerApplication::HandlePacket(SerialPacket packet) { - switch(packet.meta.type) { - case SerialPacket::Type::BROADCAST_REQUEST: - HandleBroadcastRequest(packet); - break; - case SerialPacket::Type::JOIN_REQUEST: - HandleJoinRequest(packet); - break; - case SerialPacket::Type::SYNCHRONIZE: - HandleSynchronize(packet); - break; - case SerialPacket::Type::DISCONNECT: - HandleDisconnect(packet); - break; - case SerialPacket::Type::SHUTDOWN: - HandleShutdown(packet); - break; - case SerialPacket::Type::CHARACTER_UPDATE: - HandleCharacterUpdate(packet); - break; - case SerialPacket::Type::REGION_REQUEST: - HandleRegionRequest(packet); - break; - //handle errors - default: - throw(std::runtime_error("Unknown SerialPacketType encountered")); - break; - } -} From 5c8572d8116b19710c57e6c8c0945890a5b1382d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 22:57:10 +1000 Subject: [PATCH 10/34] Rearranged the methods --- server/server_application.cpp | 96 ++++++++++++++++++++++------------- server/server_application.hpp | 62 +++++++++++----------- 2 files changed, 94 insertions(+), 64 deletions(-) diff --git a/server/server_application.cpp b/server/server_application.cpp index 8cd135f..12c8589 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -29,7 +29,7 @@ #include //------------------------- -//Define the public members +//public methods //------------------------- void ServerApplication::Init(int argc, char** argv) { @@ -75,17 +75,13 @@ void ServerApplication::Init(int argc, char** argv) { //Setup the objects //------------------------- - //setup the map object - regionPager.GetAllocator()->SetLuaState(luaState); - regionPager.GetFormat()->SetLuaState(luaState); - regionPager.GetFormat()->SetSaveDir(config["dir.maps"] + config["map.savename"]); - std::cout << "Prepared the map system" << std::endl; + accountMgr.SetDatabase(database); + characterMgr.SetDatabase(database); - //push the pager onto the lua registry - lua_pushstring(luaState, "pager"); - lua_pushlightuserdata(luaState, reinterpret_cast(®ionPager)); - lua_settable(luaState, LUA_REGISTRYINDEX); - std::cout << "Registered the map system in lua" << std::endl; + combatMgr.SetLuaState(luaState); + roomMgr.SetLuaState(luaState); + + std::cout << "Internal managers ready" << std::endl; //------------------------- //Run the startup scripts @@ -103,16 +99,21 @@ void ServerApplication::Init(int argc, char** argv) { } std::cout << "Completed lua's setup script" << std::endl; + //------------------------- //debug output + //------------------------- + std::cout << "Internal sizes:" << std::endl; - std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl; - std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl; + std::cout << "\tTile Size: " << sizeof(Region::type_t) << std::endl; + std::cout << "\tRegion Format: " << REGION_WIDTH << ", " << REGION_HEIGHT << ", " << REGION_DEPTH << << std::endl; + std::cout << "\tRegion Content Footprint: " << REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) << std::endl; + std::cout << "\tPACKET_BUFFER_SIZE (max size): " << PACKET_BUFFER_SIZE << std::endl; + //------------------------- //finalize the startup - std::cout << "Startup completed successfully" << std::endl; + //------------------------- - //debugging - // + std::cout << "Startup completed successfully" << std::endl; } void ServerApplication::Proc() { @@ -156,7 +157,7 @@ void ServerApplication::Quit() { } //------------------------- -//Define the network switch +//handle incoming traffic //------------------------- void ServerApplication::HandlePacket(SerialPacket packet) { @@ -191,9 +192,7 @@ void ServerApplication::HandlePacket(SerialPacket packet) { HandleCharacterDelete(packet); break; case SerialPacketType::CHARACTER_UPDATE: - HandleCharacterUpdate(packet); - break; - case SerialPacketType::CHARACTER_STATS_REQUEST: + case SerialPacketType::CHARACTER_STATS_REQUEST: //TODO: ? HandleCharacterUpdate(packet); break; @@ -213,7 +212,7 @@ void ServerApplication::HandlePacket(SerialPacket packet) { } //------------------------- -//Define the network handlers +//basic connections //------------------------- void ServerApplication::HandleBroadcastRequest(SerialPacket packet) { @@ -344,6 +343,37 @@ void ServerApplication::HandleShutdown(SerialPacket packet) { std::cout << "Shutdown signal accepted" << std::endl; } +//------------------------- +//map management +//------------------------- + +void ServerApplication::HandleRegionRequest(SerialPacket packet) { + //TODO: this should be moved elsewhere + packet.meta.type = SerialPacket::Type::REGION_CONTENT; + packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y); + + //send the content + network.SendTo(&packet.meta.srcAddress, &packet); +} + +//------------------------- +//combat management +//------------------------- + +//TODO: combat management + +//------------------------- +//Character Management +//------------------------- + +void ServerApplication::HandleCharacterNew(SerialPacket) { + //TODO: fill this +} + +void ServerApplication::HandleCharacterDelete(SerialPacket) { + //TODO: fill this +} + void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { //TODO: this should be moved elsewhere if (characterMap.find(packet.characterInfo.characterIndex) == characterMap.end()) { @@ -357,14 +387,17 @@ void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { PumpPacket(packet); } -void ServerApplication::HandleRegionRequest(SerialPacket packet) { - //TODO: this should be moved elsewhere - packet.meta.type = SerialPacket::Type::REGION_CONTENT; - packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y); +//------------------------- +//enemy management +//------------------------- - //send the content - network.SendTo(&packet.meta.srcAddress, &packet); -} +//TODO: enemy management + +//------------------------- +//utility methods +//------------------------- + +//TODO: a function that only sends to characters in a certain proximity void ServerApplication::PumpPacket(SerialPacket packet) { //NOTE: I don't really like this, but it'll do for now @@ -380,10 +413,3 @@ void ServerApplication::PumpCharacterUnload(int uid) { delPacket.characterInfo.characterIndex = uid; PumpPacket(delPacket); } - -//------------------------- -//Define the utility methods -//------------------------- - -//TODO: utility methods - diff --git a/server/server_application.hpp b/server/server_application.hpp index 3b24303..aa761d3 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -24,22 +24,19 @@ //server specific stuff #include "client_data.hpp" -#include "account_data.hpp" -#include "character_data.hpp" -#include "combat_data.hpp" -#include "enemy_factory_generic.hpp" +#include "account_manager.hpp" +#include "character_manager.hpp" +#include "combat_manager.hpp" +#include "room_manager.hpp" //maps #include "map_allocator.hpp" #include "map_file_format.hpp" #include "region_pager.hpp" -//networking +//common utilities #include "udp_network_utility.hpp" - -//common #include "config_utility.hpp" -#include "vector2.hpp" //APIs #include "lua/lua.hpp" @@ -51,10 +48,9 @@ #include //The main application class -//TODO: modulate this god class class ServerApplication { public: - //standard functions + //public methods ServerApplication() = default; ~ServerApplication() = default; @@ -63,47 +59,55 @@ public: void Quit(); private: + //handle incoming traffic void HandlePacket(SerialPacket); - //handle incoming traffic + //basic connections void HandleBroadcastRequest(SerialPacket); void HandleJoinRequest(SerialPacket); - void HandleSynchronize(SerialPacket); void HandleDisconnect(SerialPacket); void HandleShutdown(SerialPacket); - void HandleCharacterUpdate(SerialPacket); + + //map management void HandleRegionRequest(SerialPacket); + //combat management + //TODO: combat management + + //character management + void HandleCharacterNew(SerialPacket); + void HandleCharacterDelete(SerialPacket); + void HandleCharacterUpdate(SerialPacket); + + //enemy management + //TODO: enemy management + + //mismanagement + void HandleSynchronize(SerialPacket); + + //utility methods //TODO: a function that only sends to characters in a certain proximity void PumpPacket(SerialPacket); void PumpCharacterUnload(int uid); - //TODO: Account management - //TODO: character management - //TODO: combat management - - //APIs - UDPNetworkUtility network; + //APIs and utilities sqlite3* database = nullptr; lua_State* luaState = nullptr; + UDPNetworkUtility network; + ConfigUtility config; //server tables std::map clientMap; - std::map combatMap; - std::map enemyMap; - //maps - //TODO: I need to handle multiple map objects - //TODO: Unload regions that are distant from any characters - RegionPager regionPager; - EnemyFactoryGeneric enemyFactory; + //managers + AccountManager accountMgr; + CharacterManager characterMgr; + CombatManager combatMgr; + RoomManager roomMgr; //misc bool running = true; - ConfigUtility config; int clientUID = 0; - int combatUID = 0; - int enemyUID = 0; }; #endif From 10e857ecd1aaeb7e4b7e550be4bc3f967e9e5789 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 23:08:05 +1000 Subject: [PATCH 11/34] Added empty managers for CombatData, RoomData and EnemyData These are just placeholders for now, but I'll flesh them out later. I should note that the server's managers all build cleanly. --- server/combat_manager.cpp | 54 +++++++++++++++++++++++++++++++++++++++ server/combat_manager.hpp | 51 ++++++++++++++++++++++++++++++++++++ server/enemy_manager.cpp | 54 +++++++++++++++++++++++++++++++++++++++ server/enemy_manager.hpp | 51 ++++++++++++++++++++++++++++++++++++ server/room_manager.cpp | 54 +++++++++++++++++++++++++++++++++++++++ server/room_manager.hpp | 51 ++++++++++++++++++++++++++++++++++++ 6 files changed, 315 insertions(+) create mode 100644 server/combat_manager.cpp create mode 100644 server/combat_manager.hpp create mode 100644 server/enemy_manager.cpp create mode 100644 server/enemy_manager.hpp create mode 100644 server/room_manager.cpp create mode 100644 server/room_manager.hpp diff --git a/server/combat_manager.cpp b/server/combat_manager.cpp new file mode 100644 index 0000000..be4f9ac --- /dev/null +++ b/server/combat_manager.cpp @@ -0,0 +1,54 @@ +/* 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_manager.hpp b/server/combat_manager.hpp new file mode 100644 index 0000000..77573ab --- /dev/null +++ b/server/combat_manager.hpp @@ -0,0 +1,51 @@ +/* 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/enemy_manager.cpp b/server/enemy_manager.cpp new file mode 100644 index 0000000..2b49d3d --- /dev/null +++ b/server/enemy_manager.cpp @@ -0,0 +1,54 @@ +/* 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/enemy_manager.hpp b/server/enemy_manager.hpp new file mode 100644 index 0000000..dae86ad --- /dev/null +++ b/server/enemy_manager.hpp @@ -0,0 +1,51 @@ +/* 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/room_manager.cpp b/server/room_manager.cpp new file mode 100644 index 0000000..3cb43dd --- /dev/null +++ b/server/room_manager.cpp @@ -0,0 +1,54 @@ +/* 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 "room_manager.hpp" + +//------------------------- +//public access methods +//------------------------- + +//TODO + +//------------------------- +//accessors and mutators +//------------------------- + +RoomData* RoomManager::GetRoom(int uid) { + std::map::iterator it = roomMap.find(uid); + + if (it == roomMap.end()) { + return nullptr; + } + + return &it->second; +} + +std::map* RoomManager::GetContainer() { + return &roomMap; +} + +lua_State* RoomManager::SetLuaState(lua_State* L) { + return luaState = L; +} + +lua_State* RoomManager::GetLuaState() { + return luaState; +} diff --git a/server/room_manager.hpp b/server/room_manager.hpp new file mode 100644 index 0000000..9b1dfc6 --- /dev/null +++ b/server/room_manager.hpp @@ -0,0 +1,51 @@ +/* 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 ROOMMANAGER_HPP_ +#define ROOMMANAGER_HPP_ + +#include "room_data.hpp" + +#include "lua/lua.hpp" + +#include + +class RoomManager { +public: + RoomManager() = default; + ~RoomManager() = default; + + //public access methods + //TODO + + //accessors and mutators + RoomData* GetRoom(int uid); + std::map* GetContainer(); + + lua_State* SetLuaState(lua_State*); + lua_State* GetLuaState(); + +private: + std::map roomMap; + lua_State* luaState = nullptr; +}; + +#endif \ No newline at end of file From 170096b5db9bf5a0293254813652f7c667336ffa Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 6 Jun 2014 23:34:38 +1000 Subject: [PATCH 12/34] Server is nearly done, only server_application.cpp is failing --- client/makefile | 2 +- server/account_manager.cpp | 10 ++++++++++ server/account_manager.hpp | 4 ++-- server/character_manager.cpp | 10 ++++++++++ server/character_manager.hpp | 4 ++-- server/makefile | 2 +- server/server_application.cpp | 14 +------------- server/server_application.hpp | 6 ++++-- 8 files changed, 31 insertions(+), 21 deletions(-) diff --git a/client/makefile b/client/makefile index bba3c67..947b822 100644 --- a/client/makefile +++ b/client/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../common/gameplay ../common/graphics ../common/map ../common/network ../common/ui ../common/utilities +INCLUDES+=. ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS diff --git a/server/account_manager.cpp b/server/account_manager.cpp index 424c125..4a9bdc4 100644 --- a/server/account_manager.cpp +++ b/server/account_manager.cpp @@ -36,6 +36,16 @@ static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;"; //Define the public methods //------------------------- +AccountManager::AccountManager() { + // +} + +AccountManager::~AccountManager() { + for (auto& it : accountMap) { + SaveUserAccount(it.first); + } +} + int AccountManager::CreateUserAccount(std::string username, int clientIndex) { //create this user account, failing if it exists, leave this account in memory sqlite3_stmt* statement = nullptr; diff --git a/server/account_manager.hpp b/server/account_manager.hpp index 6d109ac..10ba8a3 100644 --- a/server/account_manager.hpp +++ b/server/account_manager.hpp @@ -30,8 +30,8 @@ class AccountManager { public: - AccountManager() = default; - ~AccountManager() = default; + AccountManager(); + ~AccountManager(); //public access methods int CreateUserAccount(std::string username, int clientIndex); diff --git a/server/character_manager.cpp b/server/character_manager.cpp index 4064f5d..1192788 100644 --- a/server/character_manager.cpp +++ b/server/character_manager.cpp @@ -58,6 +58,16 @@ static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; //Define the methods //------------------------- +CharacterManager::CharacterManager() { + // +} + +CharacterManager::~CharacterManager() { + for (auto& it : characterMap) { + SaveCharacter(it.first); + } +} + //TODO: should statistics be stored separately? //TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) { diff --git a/server/character_manager.hpp b/server/character_manager.hpp index c334a7a..97b3a18 100644 --- a/server/character_manager.hpp +++ b/server/character_manager.hpp @@ -30,8 +30,8 @@ class CharacterManager { public: - CharacterManager() = default; - ~CharacterManager() = default; + CharacterManager(); + ~CharacterManager(); //public access methods int CreateCharacter(int owner, std::string handle, std::string avatar); diff --git a/server/makefile b/server/makefile index 901f8a6..7c733ea 100644 --- a/server/makefile +++ b/server/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../common/gameplay ../common/map ../common/network ../common/script ../common/utilities +INCLUDES+=. ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/script ../common/utilities LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/server_application.cpp b/server/server_application.cpp index 12c8589..24c71cc 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -80,6 +80,7 @@ void ServerApplication::Init(int argc, char** argv) { combatMgr.SetLuaState(luaState); roomMgr.SetLuaState(luaState); + enemyMgr.SetLuaState(luaState); std::cout << "Internal managers ready" << std::endl; @@ -133,19 +134,6 @@ void ServerApplication::Proc() { void ServerApplication::Quit() { std::cout << "Shutting down" << std::endl; - //save the server state - for (auto& it : accountMap) { - SaveUserAccount(it.first); - } - for (auto& it : characterMap) { - SaveCharacter(it.first); - } - - //empty the members - accountMap.clear(); - characterMap.clear(); - regionPager.UnloadAll(); - //APIs lua_close(luaState); sqlite3_close_v2(database); diff --git a/server/server_application.hpp b/server/server_application.hpp index aa761d3..cab0e1f 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -23,10 +23,11 @@ #define SERVERAPPLICATION_HPP_ //server specific stuff -#include "client_data.hpp" #include "account_manager.hpp" #include "character_manager.hpp" +#include "client_data.hpp" #include "combat_manager.hpp" +#include "enemy_manager.hpp" #include "room_manager.hpp" //maps @@ -96,13 +97,14 @@ private: UDPNetworkUtility network; ConfigUtility config; - //server tables + //simple tables std::map clientMap; //managers AccountManager accountMgr; CharacterManager characterMgr; CombatManager combatMgr; + EnemyManager enemyMgr; RoomManager roomMgr; //misc From cac273da5e21ec9a9173eb625909231b8c40f3d9 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 7 Jun 2014 01:14:54 +1000 Subject: [PATCH 13/34] Partial rewrite of server_application.cpp I've also fixed some other issues along the way. However, the next step requires support for multiple rooms. Finally. --- common/network/packet/serial_packet_base.hpp | 3 +- server/account_manager.cpp | 20 +- server/account_manager.hpp | 10 +- server/character_manager.cpp | 12 ++ server/character_manager.hpp | 3 + server/server_application.cpp | 192 +++++++++---------- server/server_application.hpp | 22 +-- 7 files changed, 131 insertions(+), 131 deletions(-) diff --git a/common/network/packet/serial_packet_base.hpp b/common/network/packet/serial_packet_base.hpp index 16279c8..760e54a 100644 --- a/common/network/packet/serial_packet_base.hpp +++ b/common/network/packet/serial_packet_base.hpp @@ -30,6 +30,7 @@ #include "SDL/SDL_net.h" +#define NETWORK_VERSION 20140607 #define PACKET_STRING_SIZE 100 struct SerialPacketBase { @@ -39,7 +40,7 @@ struct SerialPacketBase { typedef SerialPacketType Type; - virtual ~SerialPacketBase(); + virtual ~SerialPacketBase() {}; }; typedef SerialPacketBase SerialPacket; diff --git a/server/account_manager.cpp b/server/account_manager.cpp index 4a9bdc4..2a5a968 100644 --- a/server/account_manager.cpp +++ b/server/account_manager.cpp @@ -42,11 +42,11 @@ AccountManager::AccountManager() { AccountManager::~AccountManager() { for (auto& it : accountMap) { - SaveUserAccount(it.first); + SaveAccount(it.first); } } -int AccountManager::CreateUserAccount(std::string username, int clientIndex) { +int AccountManager::CreateAccount(std::string username, int clientIndex) { //create this user account, failing if it exists, leave this account in memory sqlite3_stmt* statement = nullptr; @@ -70,10 +70,10 @@ int AccountManager::CreateUserAccount(std::string username, int clientIndex) { sqlite3_finalize(statement); //load this account into memory - return LoadUserAccount(username, clientIndex); + return LoadAccount(username, clientIndex); } -int AccountManager::LoadUserAccount(std::string username, int clientIndex) { +int AccountManager::LoadAccount(std::string username, int clientIndex) { //load this user account, failing if it is in memory, creating it if it doesn't exist sqlite3_stmt* statement = nullptr; @@ -119,13 +119,13 @@ int AccountManager::LoadUserAccount(std::string username, int clientIndex) { if (ret == SQLITE_DONE) { //create the non-existant account instead - return CreateUserAccount(username, clientIndex); + return CreateAccount(username, clientIndex); } - throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) )); + throw(std::runtime_error(std::string() + "Unknown SQL error in LoadAccount: " + sqlite3_errmsg(database) )); } -int AccountManager::SaveUserAccount(int uid) { +int AccountManager::SaveAccount(int uid) { //save this user account from memory, replacing it if it exists in the database //DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID. @@ -168,14 +168,14 @@ int AccountManager::SaveUserAccount(int uid) { return 0; } -void AccountManager::UnloadUserAccount(int uid) { +void AccountManager::UnloadAccount(int uid) { //save this user account, and then unload it //NOTE: the associated characters are unloaded externally - SaveUserAccount(uid); + SaveAccount(uid); accountMap.erase(uid); } -void AccountManager::DeleteUserAccount(int uid) { +void AccountManager::DeleteAccount(int uid) { //delete a user account from the database, and remove it from memory //NOTE: the associated characters should be deleted externally sqlite3_stmt* statement = nullptr; diff --git a/server/account_manager.hpp b/server/account_manager.hpp index 10ba8a3..5bf3841 100644 --- a/server/account_manager.hpp +++ b/server/account_manager.hpp @@ -34,11 +34,11 @@ public: ~AccountManager(); //public access methods - int CreateUserAccount(std::string username, int clientIndex); - int LoadUserAccount(std::string username, int clientIndex); - int SaveUserAccount(int uid); - void UnloadUserAccount(int uid); - void DeleteUserAccount(int uid); + int CreateAccount(std::string username, int clientIndex); + int LoadAccount(std::string username, int clientIndex); + int SaveAccount(int uid); + void UnloadAccount(int uid); + void DeleteAccount(int uid); //accessors and mutators AccountData* GetAccount(int uid); diff --git a/server/character_manager.cpp b/server/character_manager.cpp index 1192788..34310c9 100644 --- a/server/character_manager.cpp +++ b/server/character_manager.cpp @@ -283,6 +283,18 @@ void CharacterManager::DeleteCharacter(int uid) { characterMap.erase(uid); } +void CharacterManager::UnloadCharacterIf(std::function::iterator)> f) { + //save this character, then unload it if the parameter returns true + for (std::map::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) { + if (f(it)) { + SaveCharacter(it->first); + it = characterMap.erase(it); + continue; + } + it++; + } +} + //------------------------- //Define the accessors and mutators //------------------------- diff --git a/server/character_manager.hpp b/server/character_manager.hpp index 97b3a18..812d337 100644 --- a/server/character_manager.hpp +++ b/server/character_manager.hpp @@ -27,6 +27,7 @@ #include "sqlite3/sqlite3.h" #include +#include class CharacterManager { public: @@ -40,6 +41,8 @@ public: void UnloadCharacter(int uid); void DeleteCharacter(int uid); + void UnloadCharacterIf(std::function::iterator)> f); + //accessors and mutators CharacterData* GetCharacter(int uid); std::map* GetContainer(); diff --git a/server/server_application.cpp b/server/server_application.cpp index 24c71cc..7ef5f45 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -106,7 +106,7 @@ void ServerApplication::Init(int argc, char** argv) { std::cout << "Internal sizes:" << std::endl; std::cout << "\tTile Size: " << sizeof(Region::type_t) << std::endl; - std::cout << "\tRegion Format: " << REGION_WIDTH << ", " << REGION_HEIGHT << ", " << REGION_DEPTH << << std::endl; + std::cout << "\tRegion Format: " << REGION_WIDTH << ", " << REGION_HEIGHT << ", " << REGION_DEPTH << std::endl; std::cout << "\tRegion Content Footprint: " << REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) << std::endl; std::cout << "\tPACKET_BUFFER_SIZE (max size): " << PACKET_BUFFER_SIZE << std::endl; @@ -122,7 +122,7 @@ void ServerApplication::Proc() { while(running) { //suck in the waiting packets & process them while(network.Receive(&packet)) { - HandlePacket(packet); + HandlePacket(&packet); } //update the internals //TODO: update the internals i.e. player positions @@ -148,25 +148,25 @@ void ServerApplication::Quit() { //handle incoming traffic //------------------------- -void ServerApplication::HandlePacket(SerialPacket packet) { - switch(packet.meta.type) { +void ServerApplication::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { //basic connections case SerialPacketType::BROADCAST_REQUEST: - HandleBroadcastRequest(packet); + HandleBroadcastRequest(dynamic_cast(argPacket)); break; case SerialPacketType::JOIN_REQUEST: - HandleJoinRequest(packet); + HandleJoinRequest(dynamic_cast(argPacket)); break; case SerialPacketType::DISCONNECT: - HandleDisconnect(packet); + HandleDisconnect(dynamic_cast(argPacket)); break; case SerialPacketType::SHUTDOWN: - HandleShutdown(packet); + HandleShutdown(dynamic_cast(argPacket)); break; //map management case SerialPacketType::REGION_REQUEST: - HandleRegionRequest(packet); + HandleRegionRequest(dynamic_cast(argPacket)); break; //combat management @@ -174,14 +174,14 @@ void ServerApplication::HandlePacket(SerialPacket packet) { //character management case SerialPacketType::CHARACTER_NEW: - HandleCharacterNew(packet); + HandleCharacterNew(dynamic_cast(argPacket)); break; case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(packet); + HandleCharacterDelete(dynamic_cast(argPacket)); break; case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_STATS_REQUEST: //TODO: ? - HandleCharacterUpdate(packet); + HandleCharacterUpdate(dynamic_cast(argPacket)); break; //enemy management @@ -189,12 +189,12 @@ void ServerApplication::HandlePacket(SerialPacket packet) { //mismanagement case SerialPacketType::SYNCHRONIZE: - HandleSynchronize(packet); + HandleSynchronize(dynamic_cast(argPacket)); break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(int(packet.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(int(argPacket->type)))); break; } } @@ -203,129 +203,82 @@ void ServerApplication::HandlePacket(SerialPacket packet) { //basic connections //------------------------- -void ServerApplication::HandleBroadcastRequest(SerialPacket packet) { - //pack the server's data - packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE; - packet.serverInfo.networkVersion = NETWORK_VERSION; - snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); - packet.serverInfo.playerCount = characterMap.size(); +void ServerApplication::HandleBroadcastRequest(SerialPacket* const argPacket) { + //send the server's data + ServerPacket newPacket; - //bounce this packet - network.SendTo(&packet.meta.srcAddress, &packet); + newPacket.type = SerialPacketType::BROADCAST_RESPONSE; + snprintf(newPacket.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); + newPacket.playerCount = characterMgr.GetContainer()->size(); + newPacket.version = NETWORK_VERSION; + + network.SendTo(&argPacket->srcAddress, dynamic_cast(&newPacket)); } -void ServerApplication::HandleJoinRequest(SerialPacket packet) { +void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { //create the new client ClientData newClient; - newClient.address = packet.meta.srcAddress; + newClient.address = argPacket->srcAddress; //load the user account - int accountIndex = LoadUserAccount(packet.clientInfo.username, clientUID); + //TODO: handle passwords + int accountIndex = accountMgr.LoadAccount(argPacket->username, clientUID); if (accountIndex < 0) { //TODO: send rejection packet std::cerr << "Error: Account already loaded: " << accountIndex << std::endl; return; } - //load the new character - int characterIndex = LoadCharacter(accountIndex, packet.clientInfo.handle, packet.clientInfo.avatar); - if (characterIndex < 0) { - //TODO: send rejection packet - std::cerr << "Error: Character already loaded: " << characterIndex << std::endl; - UnloadUserAccount(accountIndex); - return; - } - //send the client their info - packet.meta.type = SerialPacket::Type::JOIN_RESPONSE; - packet.clientInfo.clientIndex = clientUID; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + ClientPacket newPacket; + newPacket.type = SerialPacketType::JOIN_RESPONSE; + newPacket.clientIndex = clientUID; + newPacket.accountIndex = accountIndex; - //bounce this packet - network.SendTo(&newClient.address, &packet); + network.SendTo(&newClient.address, dynamic_cast(&newPacket)); - //reference to prevent multiple lookups - //TODO: I need a way to pack structures unto packets more easily - //NOTE: this chunk of code is similar to HandleSynchronize - CharacterData& character = characterMap[characterIndex]; - - //send the new character to all clients - packet.meta.type = SerialPacket::Type::CHARACTER_NEW; - packet.characterInfo.characterIndex = characterIndex; - strncpy(packet.characterInfo.handle, character.handle.c_str(), PACKET_STRING_SIZE); - strncpy(packet.characterInfo.avatar, character.avatar.c_str(), PACKET_STRING_SIZE); - packet.characterInfo.mapIndex = character.mapIndex; - packet.characterInfo.origin = character.origin; - packet.characterInfo.motion = character.motion; - packet.characterInfo.stats = character.stats; - - PumpPacket(packet); - - //TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?) //finished this routine clientMap[clientUID++] = newClient; - std::cout << "Connect, total: " << clientMap.size() << std::endl; + std::cout << "New connection, " << clientMap.size() << " clients and " << accountMgr.GetContainer()->size() << " accounts total" << std::endl; } -void ServerApplication::HandleSynchronize(SerialPacket packet) { - //TODO: compensate for large distances - - //send all the server's data to this client - SerialPacket newPacket; - - //characters - newPacket.meta.type = SerialPacket::Type::CHARACTER_UPDATE; - for (auto& it : characterMap) { - //TODO: update this for the expanded CharacterData structure - newPacket.characterInfo.characterIndex = it.first; - snprintf(newPacket.characterInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); - snprintf(newPacket.characterInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); - newPacket.characterInfo.mapIndex = it.second.mapIndex; - newPacket.characterInfo.origin = it.second.origin; - newPacket.characterInfo.motion = it.second.motion; - newPacket.characterInfo.stats = it.second.stats; - - network.SendTo(&clientMap[packet.clientInfo.clientIndex].address, &newPacket); - } -} - -void ServerApplication::HandleDisconnect(SerialPacket packet) { +void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { //TODO: authenticate who is disconnecting/kicking //forward to the specified client - network.SendTo(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, &packet); + network.SendTo( + &clientMap[ accountMgr.GetAccount(argPacket->accountIndex)->clientIndex ].address, + dynamic_cast(argPacket) + ); - //unload client and server-side characters - for (std::map::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) { - if (it->second.owner == packet.clientInfo.accountIndex) { + //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) { PumpCharacterUnload(it->first); - SaveCharacter(it->first); - it = characterMap.erase(it); //efficient - continue; + return true; } - else { - ++it; - } - } + return false; + }); //erase the in-memory stuff - clientMap.erase(accountMap[packet.clientInfo.accountIndex].clientIndex); - UnloadUserAccount(packet.clientInfo.accountIndex); + clientMap.erase(accountMgr.GetAccount(argPacket->accountIndex)->clientIndex); + accountMgr.UnloadAccount(argPacket->accountIndex); //finished this routine - std::cout << "Disconnect, total: " << clientMap.size() << std::endl; + std::cout << "Disconnection, " << clientMap.size() << " clients and " << accountMgr.GetContainer()->size() << " accounts total" << std::endl; } -void ServerApplication::HandleShutdown(SerialPacket packet) { +void ServerApplication::HandleShutdown(SerialPacket* const argPacket) { //TODO: authenticate who is shutting the server down //end the server running = false; //disconnect all clients - packet.meta.type = SerialPacket::Type::DISCONNECT; - PumpPacket(packet); + SerialPacket newPacket; + newPacket.type = SerialPacketType::DISCONNECT; + PumpPacket(&newPacket); //finished this routine std::cout << "Shutdown signal accepted" << std::endl; @@ -335,13 +288,18 @@ void ServerApplication::HandleShutdown(SerialPacket packet) { //map management //------------------------- -void ServerApplication::HandleRegionRequest(SerialPacket packet) { - //TODO: this should be moved elsewhere - packet.meta.type = SerialPacket::Type::REGION_CONTENT; - packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y); +void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { + RegionPacket newPacket; + + newPacket.type = SerialPacketType::REGION_CONTENT; + newPacket.roomIndex = argPacket->roomIndex; + newPacket.x = argPacket->x; + newPacket.y = argPacket->y; + + newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y); //send the content - network.SendTo(&packet.meta.srcAddress, &packet); + network.SendTo(&argPacket->srcAddress, dynamic_cast(argPacket)); } //------------------------- @@ -381,6 +339,32 @@ void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { //TODO: enemy management +//------------------------- +//mismanagement +//------------------------- + +void ServerApplication::HandleSynchronize(SerialPacket packet) { + //TODO: compensate for large distances + + //send all the server's data to this client + SerialPacket newPacket; + + //characters + newPacket.meta.type = SerialPacket::Type::CHARACTER_UPDATE; + for (auto& it : characterMap) { + //TODO: update this for the expanded CharacterData structure + newPacket.characterInfo.characterIndex = it.first; + snprintf(newPacket.characterInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); + snprintf(newPacket.characterInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); + newPacket.characterInfo.mapIndex = it.second.mapIndex; + newPacket.characterInfo.origin = it.second.origin; + newPacket.characterInfo.motion = it.second.motion; + newPacket.characterInfo.stats = it.second.stats; + + network.SendTo(&clientMap[packet.clientInfo.clientIndex].address, &newPacket); + } +} + //------------------------- //utility methods //------------------------- diff --git a/server/server_application.hpp b/server/server_application.hpp index cab0e1f..a0cb9b3 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -61,34 +61,34 @@ public: private: //handle incoming traffic - void HandlePacket(SerialPacket); + void HandlePacket(SerialPacket* const); //basic connections - void HandleBroadcastRequest(SerialPacket); - void HandleJoinRequest(SerialPacket); - void HandleDisconnect(SerialPacket); - void HandleShutdown(SerialPacket); + void HandleBroadcastRequest(SerialPacket* const); + void HandleJoinRequest(ClientPacket* const); + void HandleDisconnect(ClientPacket* const); + void HandleShutdown(SerialPacket* const); //map management - void HandleRegionRequest(SerialPacket); + void HandleRegionRequest(RegionPacket* const); //combat management //TODO: combat management //character management - void HandleCharacterNew(SerialPacket); - void HandleCharacterDelete(SerialPacket); - void HandleCharacterUpdate(SerialPacket); + void HandleCharacterNew(SerialPacket* const); + void HandleCharacterDelete(SerialPacket* const); + void HandleCharacterUpdate(SerialPacket* const); //enemy management //TODO: enemy management //mismanagement - void HandleSynchronize(SerialPacket); + void HandleSynchronize(SerialPacket* const); //utility methods //TODO: a function that only sends to characters in a certain proximity - void PumpPacket(SerialPacket); + void PumpPacket(SerialPacket* const); void PumpCharacterUnload(int uid); //APIs and utilities From 63be0ee70d3e9c236d06e05557bda876fe8b42d7 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 7 Jun 2014 02:12:40 +1000 Subject: [PATCH 14/34] The server is building, but still needs work There is some missing character creation/unloading code, and there are a few other issues highlighted by TODO tags, see below. In general, 'mapIndex' has been renamed to 'roomIndex'. Multiple rooms have not been fully implemented yet, but I'm working on it. Other issues: * FileFormat needs to be changed to MapLoader * Server's character movement is still slaved to the clients The client does not build. --- common/gameplay/character_data.hpp | 2 +- common/map/map_file_format.hpp | 2 + common/map/region.hpp | 6 +- common/script/map_api.cpp | 2 + rsc/scripts/setup_server.sql | 2 +- server/character_manager.cpp | 6 +- server/room_data.hpp | 16 ++++-- server/room_manager.hpp | 1 + server/server_application.cpp | 91 +++++++++++++++++++----------- server/server_application.hpp | 13 ++--- 10 files changed, 85 insertions(+), 56 deletions(-) diff --git a/common/gameplay/character_data.hpp b/common/gameplay/character_data.hpp index ff129b2..361788b 100644 --- a/common/gameplay/character_data.hpp +++ b/common/gameplay/character_data.hpp @@ -45,7 +45,7 @@ struct CharacterData { std::string avatar; //world position - int mapIndex = 0; + int roomIndex = 0; Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; Vector2 bounds = {0.0,0.0}; diff --git a/common/map/map_file_format.hpp b/common/map/map_file_format.hpp index 92f0c8d..75f5204 100644 --- a/common/map/map_file_format.hpp +++ b/common/map/map_file_format.hpp @@ -28,6 +28,8 @@ #include +//TODO: I'm unhappy with using this system, there needs to be a way to handle saving/loading better + class DummyFormat { public: void Load(Region** const, int x, int y); diff --git a/common/map/region.hpp b/common/map/region.hpp index 560161b..4c0d2cd 100644 --- a/common/map/region.hpp +++ b/common/map/region.hpp @@ -22,9 +22,9 @@ #ifndef REGION_HPP_ #define REGION_HPP_ -#define REGION_WIDTH 20 -#define REGION_HEIGHT 20 -#define REGION_DEPTH 3 +constexpr int REGION_WIDTH = 20; +constexpr int REGION_HEIGHT = 20; +constexpr int REGION_DEPTH = 3; class Region { public: diff --git a/common/script/map_api.cpp b/common/script/map_api.cpp index 9ecfea4..0bcaf80 100644 --- a/common/script/map_api.cpp +++ b/common/script/map_api.cpp @@ -27,6 +27,8 @@ #include "region_pager.hpp" //NOTE: When operating on a region, setTile() & getTile() *are not* zero indexed, but when operating on the entire map they *are* zero indexed. +//TODO: enforce all possible parameter counts +//TODO: update the map API to handle multiple rooms static int setTile(lua_State* L) { if (lua_gettop(L) == 5) { diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index 04a6aab..88d0a82 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS Characters ( birth timestamp NOT NULL DEFAULT (datetime()), --position - mapIndex INTEGER DEFAULT 0, + roomIndex INTEGER DEFAULT 0, originX INTEGER DEFAULT 0, originY INTEGER DEFAULT 0, diff --git a/server/character_manager.cpp b/server/character_manager.cpp index 34310c9..5767e60 100644 --- a/server/character_manager.cpp +++ b/server/character_manager.cpp @@ -33,7 +33,7 @@ static const char* CREATE_CHARACTER = "INSERT INTO Characters (owner, handle, av static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;"; static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET " - "mapIndex = ?2," + "roomIndex = ?2," "originX = ?3," "originY = ?4," "level = ?5," @@ -148,7 +148,7 @@ int CharacterManager::LoadCharacter(int owner, std::string handle, std::string a //Don't cache the birth //world origin - newChar.mapIndex = sqlite3_column_int(statement, 5); + newChar.roomIndex = sqlite3_column_int(statement, 5); newChar.origin.x = (double)sqlite3_column_int(statement, 6); newChar.origin.y = (double)sqlite3_column_int(statement, 7); @@ -208,7 +208,7 @@ int CharacterManager::SaveCharacter(int uid) { //parameters bool ret = false; ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 2, character.mapIndex) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK; diff --git a/server/room_data.hpp b/server/room_data.hpp index 6826314..c436d54 100644 --- a/server/room_data.hpp +++ b/server/room_data.hpp @@ -22,6 +22,11 @@ #ifndef ROOMDATA_HPP_ #define ROOMDATA_HPP_ +//map system +#include "map_allocator.hpp" +#include "map_file_format.hpp" +#include "region_pager.hpp" + struct RoomData { enum class RoomType { OVERWORLD, @@ -31,11 +36,12 @@ struct RoomData { CAVES, }; - /* TODO: more - * "multiple rooms system" using this structure - * Pager - * collision map - */ + //members + RegionPager pager; + RoomType type; + + //TODO: collision map + //TODO: NPCs? }; #endif diff --git a/server/room_manager.hpp b/server/room_manager.hpp index 9b1dfc6..2caadaa 100644 --- a/server/room_manager.hpp +++ b/server/room_manager.hpp @@ -35,6 +35,7 @@ public: //public access methods //TODO + //TODO: setup the pagers and functors of each room object //accessors and mutators RoomData* GetRoom(int uid); diff --git a/server/server_application.cpp b/server/server_application.cpp index 7ef5f45..836af2b 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -174,14 +174,14 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { //character management case SerialPacketType::CHARACTER_NEW: - HandleCharacterNew(dynamic_cast(argPacket)); + HandleCharacterNew(dynamic_cast(argPacket)); break; case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(dynamic_cast(argPacket)); + HandleCharacterDelete(dynamic_cast(argPacket)); break; case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_STATS_REQUEST: //TODO: ? - HandleCharacterUpdate(dynamic_cast(argPacket)); + HandleCharacterUpdate(dynamic_cast(argPacket)); break; //enemy management @@ -189,7 +189,7 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { //mismanagement case SerialPacketType::SYNCHRONIZE: - HandleSynchronize(dynamic_cast(argPacket)); + HandleSynchronize(dynamic_cast(argPacket)); break; //handle errors @@ -296,7 +296,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { newPacket.x = argPacket->x; newPacket.y = argPacket->y; - newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y); + newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->pager.GetRegion(argPacket->x, argPacket->y); //send the content network.SendTo(&argPacket->srcAddress, dynamic_cast(argPacket)); @@ -312,25 +312,46 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { //Character Management //------------------------- -void ServerApplication::HandleCharacterNew(SerialPacket) { +void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) { //TODO: fill this } -void ServerApplication::HandleCharacterDelete(SerialPacket) { +void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) { //TODO: fill this } -void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { - //TODO: this should be moved elsewhere - if (characterMap.find(packet.characterInfo.characterIndex) == characterMap.end()) { - throw(std::runtime_error("Cannot update a non-existant character")); +void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) { + CharacterData* character = characterMgr.GetCharacter(argPacket->characterIndex); + + //make a new character if this one doesn't exist + if (!character) { + //this isn't normal + std::cerr << "Warning: HandleCharacterUpdate() is passing to HandleCharacterNew()" << std::endl; + HandleCharacterNew(argPacket); + return; } - //TODO: the server needs it's own movement system too - characterMap[packet.characterInfo.characterIndex].origin = packet.characterInfo.origin; - characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion; + /* TODO: rewrite this design flaw, read more + * Slaving the client to the server here is a terrible idea, instead there + * needs to be a utility function to update and send the server-side character + * to the clients. + * + * Other things to consider include functionality to reequip the character, + * apply status effects and to change the stats as well. These should all be + * handled server-side. + */ + character->roomIndex = argPacket->roomIndex; + character->origin = argPacket->origin; + character->motion = argPacket->motion; - PumpPacket(packet); + character->stats = argPacket->stats; + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs + + PumpPacket(argPacket); } //------------------------- @@ -343,26 +364,29 @@ void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { //mismanagement //------------------------- -void ServerApplication::HandleSynchronize(SerialPacket packet) { +void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) { //TODO: compensate for large distances + //TODO: I quite dislike this function //send all the server's data to this client - SerialPacket newPacket; + CharacterPacket characterPacket; //characters - newPacket.meta.type = SerialPacket::Type::CHARACTER_UPDATE; - for (auto& it : characterMap) { + characterPacket.type = SerialPacketType::CHARACTER_UPDATE; + for (auto& it : *characterMgr.GetContainer()) { //TODO: update this for the expanded CharacterData structure - newPacket.characterInfo.characterIndex = it.first; - snprintf(newPacket.characterInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); - snprintf(newPacket.characterInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); - newPacket.characterInfo.mapIndex = it.second.mapIndex; - newPacket.characterInfo.origin = it.second.origin; - newPacket.characterInfo.motion = it.second.motion; - newPacket.characterInfo.stats = it.second.stats; + characterPacket.characterIndex = it.first; + snprintf(characterPacket.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); + snprintf(characterPacket.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); + characterPacket.roomIndex = it.second.roomIndex; + characterPacket.origin = it.second.origin; + characterPacket.motion = it.second.motion; + characterPacket.stats = it.second.stats; - network.SendTo(&clientMap[packet.clientInfo.clientIndex].address, &newPacket); + network.SendTo(&clientMap[argPacket->clientIndex].address, dynamic_cast(&characterPacket)); } + + //TODO: more } //------------------------- @@ -371,17 +395,16 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) { //TODO: a function that only sends to characters in a certain proximity -void ServerApplication::PumpPacket(SerialPacket packet) { - //NOTE: I don't really like this, but it'll do for now +void ServerApplication::PumpPacket(SerialPacket* const argPacket) { for (auto& it : clientMap) { - network.SendTo(&it.second.address, &packet); + network.SendTo(&it.second.address, argPacket); } } void ServerApplication::PumpCharacterUnload(int uid) { //delete the client-side character(s) - SerialPacket delPacket; - delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; - delPacket.characterInfo.characterIndex = uid; - PumpPacket(delPacket); + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_DELETE; + newPacket.characterIndex = uid; + PumpPacket(dynamic_cast(&newPacket)); } diff --git a/server/server_application.hpp b/server/server_application.hpp index a0cb9b3..05168df 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -30,11 +30,6 @@ #include "enemy_manager.hpp" #include "room_manager.hpp" -//maps -#include "map_allocator.hpp" -#include "map_file_format.hpp" -#include "region_pager.hpp" - //common utilities #include "udp_network_utility.hpp" #include "config_utility.hpp" @@ -76,15 +71,15 @@ private: //TODO: combat management //character management - void HandleCharacterNew(SerialPacket* const); - void HandleCharacterDelete(SerialPacket* const); - void HandleCharacterUpdate(SerialPacket* const); + void HandleCharacterNew(CharacterPacket* const); + void HandleCharacterDelete(CharacterPacket* const); + void HandleCharacterUpdate(CharacterPacket* const); //enemy management //TODO: enemy management //mismanagement - void HandleSynchronize(SerialPacket* const); + void HandleSynchronize(ClientPacket* const); //utility methods //TODO: a function that only sends to characters in a certain proximity From ee2ac0b7a9ae854c072ab0c6fc417131d02ea98f Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 8 Jun 2014 00:36:05 +1000 Subject: [PATCH 15/34] Created MAX_PACKET_SIZE --- common/network/packet/serial_packet.hpp | 10 ++++++++++ server/server_application.cpp | 21 ++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/common/network/packet/serial_packet.hpp b/common/network/packet/serial_packet.hpp index 7b7137f..44198aa 100644 --- a/common/network/packet/serial_packet.hpp +++ b/common/network/packet/serial_packet.hpp @@ -31,4 +31,14 @@ //NOTE: SerialPacket is defined in serial_packet_base.hpp +union MaxPacket { + CharacterPacket a; + ClientPacket b; + CombatPacket c; + EnemyPacket d; + RegionPacket e; + ServerPacket f; +}; +constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket); + #endif diff --git a/server/server_application.cpp b/server/server_application.cpp index 836af2b..f4dd348 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -115,14 +115,29 @@ void ServerApplication::Init(int argc, char** argv) { //------------------------- std::cout << "Startup completed successfully" << std::endl; + + //------------------------- + //debugging + //------------------------- + + std::cout << "Debugging dump:" << std::endl; + std::cout << "\tMAX_PACKET_SIZE:\t\t" << MAX_PACKET_SIZE << std::endl; + std::cout << "\tsizeof(SerialPacket):\t\t" << sizeof(SerialPacket) << std::endl; + std::cout << "\tsizeof(CharacterPacket):\t" << sizeof(CharacterPacket) << std::endl; + std::cout << "\t\tsizeof(Statistics):\t" << sizeof(Statistics) << std::endl; + std::cout << "\tsizeof(ClientPacket):\t\t" << sizeof(ClientPacket) << std::endl; + std::cout << "\tsizeof(CombatPacket):\t\t" << sizeof(CombatPacket) << std::endl; + std::cout << "\tsizeof(EnemyPacket):\t\t" << sizeof(EnemyPacket) << std::endl; + std::cout << "\tsizeof(RegionPacket):\t\t" << sizeof(RegionPacket) << std::endl; + std::cout << "\tsizeof(ServerPacket):\t\t" << sizeof(ServerPacket) << std::endl; } void ServerApplication::Proc() { - SerialPacket packet; + char packetBuffer[MAX_PACKET_SIZE]; while(running) { //suck in the waiting packets & process them - while(network.Receive(&packet)) { - HandlePacket(&packet); + while(network.Receive(reinterpret_cast(packetBuffer))) { + HandlePacket(reinterpret_cast(packetBuffer)); } //update the internals //TODO: update the internals i.e. player positions From 5175a4e40d45037012473393b7d407b1ac5bf1f4 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 8 Jun 2014 02:51:12 +1000 Subject: [PATCH 16/34] Fleshed out and rewrote some code Fleshed out HandleCharacterNew() and HandleCharacterDelete(), and rewrote HandleSynchronize(). --- server/character_manager.cpp | 1 - server/server_application.cpp | 91 +++++++++++++++++++++++++++-------- server/server_application.hpp | 1 + todo.txt | 11 +++-- 4 files changed, 81 insertions(+), 23 deletions(-) diff --git a/server/character_manager.cpp b/server/character_manager.cpp index 5767e60..0a1d4d7 100644 --- a/server/character_manager.cpp +++ b/server/character_manager.cpp @@ -68,7 +68,6 @@ CharacterManager::~CharacterManager() { } } -//TODO: should statistics be stored separately? //TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) { //Create the character, failing if it exists diff --git a/server/server_application.cpp b/server/server_application.cpp index f4dd348..44467a0 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -195,7 +195,7 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { HandleCharacterDelete(dynamic_cast(argPacket)); break; case SerialPacketType::CHARACTER_UPDATE: - case SerialPacketType::CHARACTER_STATS_REQUEST: //TODO: ? + case SerialPacketType::CHARACTER_STATS_REQUEST: HandleCharacterUpdate(dynamic_cast(argPacket)); break; @@ -328,11 +328,52 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { //------------------------- void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) { - //TODO: fill this + int characterIndex = characterMgr.CreateCharacter(argPacket->accountIndex, argPacket->handle, argPacket->avatar); + + if (characterIndex == -1) { + //TODO: rejection packet + std::cerr << "Warning: Character already loaded" << std::endl; + return; + } + + if (characterIndex == -2) { + //TODO: rejection packet + std::cerr << "Warning: Character already exists" << std::endl; + return; + } + + //send this new character to all clients + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_NEW; + CopyCharacterToPacket(&newPacket, characterIndex); + PumpPacket(&newPacket); } void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) { - //TODO: fill this + //NOTE: Disconnecting only unloads a character, this explicitly deletes it + + //Authenticate the owner is doing this + int characterIndex = characterMgr.LoadCharacter(argPacket->accountIndex, argPacket->handle, argPacket->avatar); + + //if this is not your character + if (characterIndex == -2) { + //TODO: rejection packet + std::cerr << "Warning: Character cannot be deleted" << std::endl; + + //unload an unneeded character + if (characterIndex != -1) { + characterMgr.UnloadCharacter(characterIndex); + } + return; + } + + //delete it + characterMgr.DeleteCharacter(characterIndex); + + //TODO: success packet + + //Unload this character from all clients + PumpCharacterUnload(characterIndex); } void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) { @@ -381,27 +422,22 @@ void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) { //TODO: compensate for large distances - //TODO: I quite dislike this function + //NOTE: I quite dislike this function - //send all the server's data to this client - CharacterPacket characterPacket; + //send all of the server's data to this client + ClientData& client = clientMap[argPacket->clientIndex]; + + //send all characters + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_UPDATE; - //characters - characterPacket.type = SerialPacketType::CHARACTER_UPDATE; for (auto& it : *characterMgr.GetContainer()) { - //TODO: update this for the expanded CharacterData structure - characterPacket.characterIndex = it.first; - snprintf(characterPacket.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); - snprintf(characterPacket.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); - characterPacket.roomIndex = it.second.roomIndex; - characterPacket.origin = it.second.origin; - characterPacket.motion = it.second.motion; - characterPacket.stats = it.second.stats; - - network.SendTo(&clientMap[argPacket->clientIndex].address, dynamic_cast(&characterPacket)); + newPacket.characterIndex = it.first; + CopyCharacterToPacket(&newPacket, it.first); + network.SendTo(&client.address, dynamic_cast(&newPacket)); } - //TODO: more + //TODO: more in HandleSynchronize() } //------------------------- @@ -423,3 +459,20 @@ void ServerApplication::PumpCharacterUnload(int uid) { newPacket.characterIndex = uid; PumpPacket(dynamic_cast(&newPacket)); } + +void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { + CharacterData* character = characterMgr.GetCharacter(characterIndex); + if (!character) { + throw(std::runtime_error("Failed to copy a character to a packet")); + } + + //TODO: keep this up to date when the character changes + packet->characterIndex = characterIndex; + snprintf(packet->handle, PACKET_STRING_SIZE, "%s", character->handle.c_str()); + snprintf(packet->avatar, PACKET_STRING_SIZE, "%s", character->avatar.c_str()); + packet->accountIndex = character->owner; + packet->roomIndex = character->roomIndex; + packet->origin = character->origin; + packet->motion = character->motion; + packet->stats = character->stats; +} \ No newline at end of file diff --git a/server/server_application.hpp b/server/server_application.hpp index 05168df..ca2129b 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -85,6 +85,7 @@ private: //TODO: a function that only sends to characters in a certain proximity void PumpPacket(SerialPacket* const); void PumpCharacterUnload(int uid); + void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); //APIs and utilities sqlite3* database = nullptr; diff --git a/todo.txt b/todo.txt index fa7d60d..605e60a 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,11 @@ -TODO: Modulate this god class -TODO: Segment SerialPacket? -TODO: Not all structures in common/gameplay are needed by the client +TODO: MapLoader, in place of FileFormat +TODO: Get the rooms working +TODO: update the map API to handle multiple rooms + +TODO: Rejection packets +TODO: Authentication +TODO: server is slaved to the client + TODO: I need to keep the documentation up to date. Namely, the GDD is getting out of date. TODO: I completely forgot about status ailments TODO: Time delay for requesting region packets From f034c32c384483f437156d2c343d7a0579951588 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 8 Jun 2014 04:01:09 +1000 Subject: [PATCH 17/34] Collapsed the pager into a single file, removing lua hooks I need to re-add the lua hooks, but it'll be easy. --- common/map/map_allocator.cpp | 60 ---------------- common/map/map_allocator.hpp | 48 ------------- common/map/map_file_format.cpp | 66 ----------------- common/map/map_file_format.hpp | 62 ---------------- common/map/region_pager.cpp | 61 ++++++++++++++-- common/map/region_pager.hpp | 96 +++---------------------- common/network/serial/serial_region.cpp | 8 +-- common/script/map_api.cpp | 6 +- server/room_data.hpp | 4 +- server/room_manager.hpp | 1 - server/server_application.cpp | 1 + todo.txt | 1 - 12 files changed, 68 insertions(+), 346 deletions(-) delete mode 100644 common/map/map_allocator.cpp delete mode 100644 common/map/map_allocator.hpp delete mode 100644 common/map/map_file_format.cpp delete mode 100644 common/map/map_file_format.hpp diff --git a/common/map/map_allocator.cpp b/common/map/map_allocator.cpp deleted file mode 100644 index d57351c..0000000 --- a/common/map/map_allocator.cpp +++ /dev/null @@ -1,60 +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 "map_allocator.hpp" - -#include - -void BlankAllocator::Create(Region** const ptr, int x, int y) { - (*ptr) = new Region(x, y); -} - -void BlankAllocator::Unload(Region* const ptr) { - delete ptr; -} - -void LuaAllocator::Create(Region** const ptr, int x, int y) { - //something to work on - (*ptr) = new Region(x, y); - - //API hook - lua_getglobal(state, "map"); - lua_getfield(state, -1, "create"); - lua_pushlightuserdata(state, *ptr); - if (lua_pcall(state, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); - } - lua_pop(state, 1); -} - -void LuaAllocator::Unload(Region* const ptr) { - //API hook - lua_getglobal(state, "map"); - lua_getfield(state, -1, "unload"); - lua_pushlightuserdata(state, ptr); - if (lua_pcall(state, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); - } - lua_pop(state, 1); - - //clean up the memory - delete ptr; -} diff --git a/common/map/map_allocator.hpp b/common/map/map_allocator.hpp deleted file mode 100644 index 1efeaf8..0000000 --- a/common/map/map_allocator.hpp +++ /dev/null @@ -1,48 +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 MAPALLOCATOR_HPP_ -#define MAPALLOCATOR_HPP_ - -#include "region.hpp" - -#include "lua/lua.hpp" - -class BlankAllocator { -public: - void Create(Region** const, int x, int y); - void Unload(Region* const); -private: - // -}; - -class LuaAllocator { -public: - void Create(Region** const, int x, int y); - void Unload(Region* const); - - lua_State* SetLuaState(lua_State* L) { return state = L; } - lua_State* GetLuaState() { return state; } -private: - lua_State* state = nullptr; -}; - -#endif diff --git a/common/map/map_file_format.cpp b/common/map/map_file_format.cpp deleted file mode 100644 index b4366e4..0000000 --- a/common/map/map_file_format.cpp +++ /dev/null @@ -1,66 +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 "map_file_format.hpp" - -#include - -void DummyFormat::Load(Region** const ptr, int x, int y) { - //EMPTY -} - -void DummyFormat::Save(Region* const ptr) { - //EMPTY -} - -void LuaFormat::Load(Region** const ptr, int x, int y) { - //something to load into - - if (!(*ptr)) { - (*ptr) = new Region(x, y); - } - - //API hook - lua_getglobal(state, "map"); - lua_getfield(state, -1, "load"); - lua_pushlightuserdata(state, *ptr); - lua_pushstring(state, saveDir.c_str()); - if (lua_pcall(state, 2, 1, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); - } - if (lua_toboolean(state, -1) == false) { - delete (*ptr); - (*ptr) = nullptr; - } - lua_pop(state, 2); -} - -void LuaFormat::Save(Region* const ptr) { - //API hook - lua_getglobal(state, "map"); - lua_getfield(state, -1, "save"); - lua_pushlightuserdata(state, ptr); - lua_pushstring(state, saveDir.c_str()); - if (lua_pcall(state, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) )); - } - lua_pop(state, 1); -} \ No newline at end of file diff --git a/common/map/map_file_format.hpp b/common/map/map_file_format.hpp deleted file mode 100644 index 75f5204..0000000 --- a/common/map/map_file_format.hpp +++ /dev/null @@ -1,62 +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 MAPFILEFORMAT_HPP_ -#define MAPFILEFORMAT_HPP_ - -#include "region.hpp" - -#include "lua/lua.hpp" - -#include - -//TODO: I'm unhappy with using this system, there needs to be a way to handle saving/loading better - -class DummyFormat { -public: - void Load(Region** const, int x, int y); - void Save(Region* const); - - std::string SetSaveDir(std::string s) { return saveDir = s; } - std::string GetSaveDir() { return saveDir; } -private: - std::string saveDir; -}; - -//TODO: verbose save file format -//TODO: compact save file format - -class LuaFormat { -public: - void Load(Region** const, int x, int y); - void Save(Region* const); - - std::string SetSaveDir(std::string s) { return saveDir = s; } - std::string GetSaveDir() { return saveDir; } - - lua_State* SetLuaState(lua_State* L) { return state = L; } - lua_State* GetLuaState() { return state; } -private: - std::string saveDir; - lua_State* state = nullptr; -}; - -#endif diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp index 90664dd..0fafd8f 100644 --- a/common/map/region_pager.cpp +++ b/common/map/region_pager.cpp @@ -23,17 +23,17 @@ #include "utility.hpp" -Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) { +Region::type_t RegionPager::SetTile(int x, int y, int z, Region::type_t v) { Region* ptr = GetRegion(x, y); return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v); } -Region::type_t RegionPagerBase::GetTile(int x, int y, int z) { +Region::type_t RegionPager::GetTile(int x, int y, int z) { Region* ptr = GetRegion(x, y); return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z); } -Region* RegionPagerBase::GetRegion(int x, int y) { +Region* RegionPager::GetRegion(int x, int y) { //snap the coords x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); @@ -47,7 +47,7 @@ Region* RegionPagerBase::GetRegion(int x, int y) { return CreateRegion(x, y); } -Region* RegionPagerBase::FindRegion(int x, int y) { +Region* RegionPager::FindRegion(int x, int y) { //snap the coords x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); @@ -61,7 +61,54 @@ Region* RegionPagerBase::FindRegion(int x, int y) { return nullptr; } -Region* RegionPagerBase::PushRegion(Region* ptr) { +Region* RegionPager::LoadRegion(int x, int y) { + //snap the coords + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + + //load the region if possible + //TODO: Load the region (lua) + return nullptr; +} + +Region* RegionPager::SaveRegion(int x, int y) { + //snap the coords + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + + //find & save the region + Region* ptr = FindRegion(x, y); + if (ptr) { + //TODO: save the region (lua) + } + return ptr; +} + +Region* RegionPager::CreateRegion(int x, int y) { + //snap the coords + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + + //create and push the object + Region* ptr = new Region(x, y); + //TODO: create the region (lua) regionList.push_front(ptr); - return regionList.front(); -} \ No newline at end of file + return ptr; +} + +void RegionPager::UnloadRegion(int x, int y) { + //snap the coords + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + + //custom loop, not FindRegion() + for (std::list::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) { + if ((*it)->GetX() == x && (*it)->GetY() == y) { + //TODO: unload the region (lua) + delete (*it); + it = regionList.erase(it); + continue; + } + ++it; + } +} diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index 95864f0..6a1d091 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -23,14 +23,14 @@ #define REGIONPAGER_HPP_ #include "region.hpp" -#include "utility.hpp" #include -class RegionPagerBase { +//TODO: add lua interface? +class RegionPager { public: - RegionPagerBase() {}; - virtual ~RegionPagerBase() {}; + RegionPager() = default; + ~RegionPager() = default; //tile manipulation Region::type_t SetTile(int x, int y, int z, Region::type_t v); @@ -39,14 +39,12 @@ public: //region manipulation Region* GetRegion(int x, int y); Region* FindRegion(int x, int y); - Region* PushRegion(Region*); - //interface - virtual Region* LoadRegion(int x, int y) = 0; - virtual Region* SaveRegion(int x, int y) = 0; - virtual Region* CreateRegion(int x, int y) = 0; - virtual void UnloadRegion(int x, int y) = 0; - //TODO: delete existing regions + Region* LoadRegion(int x, int y); + Region* SaveRegion(int x, int y); + Region* CreateRegion(int x, int y); + void UnloadRegion(int x, int y); + void DeleteRegion(int x, int y); //accessors & mutators std::list* GetContainer() { return ®ionList; } @@ -54,80 +52,4 @@ protected: std::list regionList; }; -template -class RegionPager : public RegionPagerBase { -public: - RegionPager() {}; - ~RegionPager() { - UnloadAll(); - } - - Region* LoadRegion(int x, int y) { - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //load the region if possible - Region* ptr = nullptr; - format.Load(&ptr, x, y); - if (ptr) { - return PushRegion(ptr); - } - return nullptr; - } - - Region* SaveRegion(int x, int y) { - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //find & save the region - Region* ptr = FindRegion(x, y); - if (ptr) { - format.Save(ptr); - } - return ptr; - } - - Region* CreateRegion(int x, int y) { - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //create and push the object - Region* ptr = nullptr; - allocator.Create(&ptr, x, y); - return PushRegion(ptr); - } - - void UnloadRegion(int x, int y) { - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //custom loop - for (std::list::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) { - if ((*it)->GetX() == x && (*it)->GetY() == y) { - allocator.Unload(*it); - it = regionList.erase(it); - continue; - } - ++it; - } - } - void UnloadAll() { - for (auto& it : regionList) { - allocator.Unload(it); - } - regionList.clear(); - } - - //accessors - Allocator* GetAllocator() { return &allocator; } - FileFormat* GetFormat() { return &format; } -protected: - Allocator allocator; - FileFormat format; -}; - #endif diff --git a/common/network/serial/serial_region.cpp b/common/network/serial/serial_region.cpp index e0860ac..31145bd 100644 --- a/common/network/serial/serial_region.cpp +++ b/common/network/serial/serial_region.cpp @@ -23,8 +23,6 @@ #include "serial_util.hpp" -#include "map_allocator.hpp" - void serializeRegionFormat(RegionPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType)); @@ -71,11 +69,7 @@ void deserializeRegionContent(RegionPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->y, sizeof(int)); //an object to work on - BlankAllocator().Create( - &packet->region, - packet->x, - packet->y - ); + packet->region = new Region(packet->x, packet->y); //content for (register int i = 0; i < REGION_WIDTH; i++) { diff --git a/common/script/map_api.cpp b/common/script/map_api.cpp index 0bcaf80..20aa681 100644 --- a/common/script/map_api.cpp +++ b/common/script/map_api.cpp @@ -22,8 +22,6 @@ #include "map_api.hpp" //map headers -#include "map_allocator.hpp" -#include "map_file_format.hpp" #include "region_pager.hpp" //NOTE: When operating on a region, setTile() & getTile() *are not* zero indexed, but when operating on the entire map they *are* zero indexed. @@ -42,7 +40,7 @@ static int setTile(lua_State* L) { lua_gettable(L, LUA_REGISTRYINDEX); //assume the pager is using lua - RegionPager* pager = reinterpret_cast*>(lua_touserdata(L, -1)); + RegionPager* pager = reinterpret_cast(lua_touserdata(L, -1)); //balance the stack lua_pop(L, 1); @@ -65,7 +63,7 @@ static int getTile(lua_State* L) { lua_gettable(L, LUA_REGISTRYINDEX); //assume the pager is using lua - RegionPager* pager = reinterpret_cast*>(lua_touserdata(L, -1)); + RegionPager* pager = reinterpret_cast(lua_touserdata(L, -1)); //balance the stack lua_pop(L, 1); diff --git a/server/room_data.hpp b/server/room_data.hpp index c436d54..0787425 100644 --- a/server/room_data.hpp +++ b/server/room_data.hpp @@ -23,8 +23,6 @@ #define ROOMDATA_HPP_ //map system -#include "map_allocator.hpp" -#include "map_file_format.hpp" #include "region_pager.hpp" struct RoomData { @@ -37,7 +35,7 @@ struct RoomData { }; //members - RegionPager pager; + RegionPager pager; RoomType type; //TODO: collision map diff --git a/server/room_manager.hpp b/server/room_manager.hpp index 2caadaa..9b1dfc6 100644 --- a/server/room_manager.hpp +++ b/server/room_manager.hpp @@ -35,7 +35,6 @@ public: //public access methods //TODO - //TODO: setup the pagers and functors of each room object //accessors and mutators RoomData* GetRoom(int uid); diff --git a/server/server_application.cpp b/server/server_application.cpp index 44467a0..0cb011d 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -23,6 +23,7 @@ #include "sql_utility.hpp" #include "serial.hpp" +#include "utility.hpp" #include #include diff --git a/todo.txt b/todo.txt index 605e60a..20fbe42 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,3 @@ -TODO: MapLoader, in place of FileFormat TODO: Get the rooms working TODO: update the map API to handle multiple rooms From b269ce5fb97e0c375994bd9eb0bb9e13a3375dc8 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 8 Jun 2014 04:20:07 +1000 Subject: [PATCH 18/34] Re-added the lua hooks --- common/map/region_pager.cpp | 61 +++++++++++++++++++++++++++++++++---- common/map/region_pager.hpp | 17 +++++++++-- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp index 0fafd8f..547b51f 100644 --- a/common/map/region_pager.cpp +++ b/common/map/region_pager.cpp @@ -23,6 +23,8 @@ #include "utility.hpp" +#include + Region::type_t RegionPager::SetTile(int x, int y, int z, Region::type_t v) { Region* ptr = GetRegion(x, y); return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v); @@ -62,13 +64,32 @@ Region* RegionPager::FindRegion(int x, int y) { } Region* RegionPager::LoadRegion(int x, int y) { + //load the region if possible + //snap the coords x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); - //load the region if possible - //TODO: Load the region (lua) - return nullptr; + Region* ptr = new Region(x, y); + + //API hook + lua_getglobal(luaState, "map"); + lua_getfield(luaState, -1, "load"); + lua_pushlightuserdata(luaState, ptr); + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + if (lua_toboolean(luaState, -1)) { + regionList.push_front(ptr); + } + else { + delete ptr; + ptr = nullptr; + } + lua_pop(luaState, 2); + + return ptr; } Region* RegionPager::SaveRegion(int x, int y) { @@ -79,7 +100,15 @@ Region* RegionPager::SaveRegion(int x, int y) { //find & save the region Region* ptr = FindRegion(x, y); if (ptr) { - //TODO: save the region (lua) + //API hook + lua_getglobal(luaState, "map"); + lua_getfield(luaState, -1, "save"); + lua_pushlightuserdata(luaState, ptr); + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + lua_pop(luaState, 1); } return ptr; } @@ -91,7 +120,16 @@ Region* RegionPager::CreateRegion(int x, int y) { //create and push the object Region* ptr = new Region(x, y); - //TODO: create the region (lua) + + //API hook + lua_getglobal(luaState, "map"); + lua_getfield(luaState, -1, "create"); + lua_pushlightuserdata(luaState, ptr); + if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + lua_pop(luaState, 1); + regionList.push_front(ptr); return ptr; } @@ -101,14 +139,25 @@ void RegionPager::UnloadRegion(int x, int y) { x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); + lua_getglobal(luaState, "map"); + //custom loop, not FindRegion() for (std::list::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) { if ((*it)->GetX() == x && (*it)->GetY() == y) { - //TODO: unload the region (lua) + + //API hook + lua_getfield(luaState, -1, "unload"); + lua_pushlightuserdata(luaState, *it); + if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + delete (*it); it = regionList.erase(it); continue; } ++it; } + + lua_pop(luaState, 1); } diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index 6a1d091..e53bc2c 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -24,9 +24,11 @@ #include "region.hpp" -#include +#include "lua/lua.hpp" + +#include +#include -//TODO: add lua interface? class RegionPager { public: RegionPager() = default; @@ -48,8 +50,17 @@ public: //accessors & mutators std::list* GetContainer() { return ®ionList; } -protected: + + std::string SetDirectory(std::string s) { return directory = s; } + std::string GetDirectory() { return directory; } + + lua_State* SetLuaState(lua_State* L) { return luaState = L; } + lua_State* GetLuaState() { return luaState; } + +private: std::list regionList; + std::string directory; + lua_State* luaState = nullptr; }; #endif From ba83fac29f1150bbcdb4514d189e99496a766dd8 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 8 Jun 2014 19:30:03 +1000 Subject: [PATCH 19/34] Changed map API to region API --- common/script/linit.cpp | 4 +- common/script/{map_api.cpp => region_api.cpp} | 64 +++---------------- common/script/{map_api.hpp => region_api.hpp} | 8 +-- 3 files changed, 16 insertions(+), 60 deletions(-) rename common/script/{map_api.cpp => region_api.cpp} (52%) rename common/script/{map_api.hpp => region_api.hpp} (87%) diff --git a/common/script/linit.cpp b/common/script/linit.cpp index 4f9eb81..c03a812 100644 --- a/common/script/linit.cpp +++ b/common/script/linit.cpp @@ -20,7 +20,7 @@ #define LUA_LIB #include "lua/lua.hpp" -#include "map_api.hpp" +#include "region_api.hpp" /* @@ -41,7 +41,7 @@ static const luaL_Reg loadedlibs[] = { {LUA_DBLIBNAME, luaopen_debug}, /* custom libs */ - {LUA_MAPLIBNAME, luaopen_mapapi}, + {LUA_REGIONLIBNAME, luaopen_regionapi}, {NULL, NULL} }; diff --git a/common/script/map_api.cpp b/common/script/region_api.cpp similarity index 52% rename from common/script/map_api.cpp rename to common/script/region_api.cpp index 20aa681..c94691b 100644 --- a/common/script/map_api.cpp +++ b/common/script/region_api.cpp @@ -19,58 +19,22 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "map_api.hpp" +#include "region_api.hpp" -//map headers -#include "region_pager.hpp" - -//NOTE: When operating on a region, setTile() & getTile() *are not* zero indexed, but when operating on the entire map they *are* zero indexed. -//TODO: enforce all possible parameter counts -//TODO: update the map API to handle multiple rooms +#include "region.hpp" static int setTile(lua_State* L) { - if (lua_gettop(L) == 5) { - //operating on a region - Region* ptr = (Region*)lua_touserdata(L, 1); - ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5)); - } - else { - //operating on the whole map - lua_pushstring(L, "pager"); - lua_gettable(L, LUA_REGISTRYINDEX); - - //assume the pager is using lua - RegionPager* pager = reinterpret_cast(lua_touserdata(L, -1)); - - //balance the stack - lua_pop(L, 1); - - pager->SetTile(lua_tointeger(L, 1), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); - } + //operating on a region + Region* ptr = (Region*)lua_touserdata(L, 1); + ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5)); return 0; } static int getTile(lua_State* L) { - if (lua_gettop(L) == 4) { - //operating on a region - Region* ptr = (Region*)lua_touserdata(L, 1); - int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1); - lua_pushnumber(L, ret); - } - else { - //operating on the whole map - lua_pushstring(L, "pager"); - lua_gettable(L, LUA_REGISTRYINDEX); - - //assume the pager is using lua - RegionPager* pager = reinterpret_cast(lua_touserdata(L, -1)); - - //balance the stack - lua_pop(L, 1); - - int ret = pager->GetTile(lua_tointeger(L, 1), lua_tointeger(L, 2), lua_tointeger(L, 3)); - lua_pushnumber(L, ret); - } + //operating on a region + Region* ptr = (Region*)lua_touserdata(L, 1); + int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1); + lua_pushnumber(L, ret); return 1; } @@ -101,15 +65,7 @@ static int getRegionDepth(lua_State* L) { return 1; } -static int dummy(lua_State* L) { - return 0; -} - static const luaL_Reg regionlib[] = { - {"create", dummy}, - {"unload", dummy}, - {"load", dummy}, - {"save", dummy}, {"settile",setTile}, {"gettile",getTile}, {"getx",getX}, @@ -120,7 +76,7 @@ static const luaL_Reg regionlib[] = { {nullptr, nullptr} }; -LUAMOD_API int luaopen_mapapi(lua_State* L) { +LUAMOD_API int luaopen_regionapi(lua_State* L) { luaL_newlib(L, regionlib); return 1; } \ No newline at end of file diff --git a/common/script/map_api.hpp b/common/script/region_api.hpp similarity index 87% rename from common/script/map_api.hpp rename to common/script/region_api.hpp index efa2abd..310074d 100644 --- a/common/script/map_api.hpp +++ b/common/script/region_api.hpp @@ -19,12 +19,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef MAPAPI_HPP_ -#define MAPAPI_HPP_ +#ifndef REGIONAPI_HPP_ +#define REGIONAPI_HPP_ #include "lua/lua.hpp" -#define LUA_MAPLIBNAME "map" -LUAMOD_API int luaopen_mapapi(lua_State* L); +#define LUA_REGIONLIBNAME "region" +LUAMOD_API int luaopen_regionapi(lua_State* L); #endif From 2d27399fd1080c6da4d82d022231e1af6b7d11a8 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 8 Jun 2014 19:43:24 +1000 Subject: [PATCH 20/34] Added the pager API placeholder files --- common/script/linit.cpp | 119 ++++++++++++++++++++---------------- common/script/pager_api.cpp | 36 +++++++++++ common/script/pager_api.hpp | 30 +++++++++ 3 files changed, 131 insertions(+), 54 deletions(-) create mode 100644 common/script/pager_api.cpp create mode 100644 common/script/pager_api.hpp diff --git a/common/script/linit.cpp b/common/script/linit.cpp index c03a812..13541f2 100644 --- a/common/script/linit.cpp +++ b/common/script/linit.cpp @@ -1,72 +1,83 @@ -/* -** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $ -** Initialization of libraries for lua.c and other clients -** See Copyright Notice in lua.h +/* $Id: linit.c,v 1.32, modified + * Initialization of libraries for lua.c and other clients + * See Copyright Notice in lua.h + * + * If you embed Lua in your program and need to open the standard + * libraries, call luaL_openlibs in your program. If you need a + * different set of libraries, copy this file to your project and edit + * it to suit your needs. + * + * Modified for use in Tortuga, renamed to linit.cpp + * Modifications are released under the zlib license: + * + * 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. */ - -/* Modified for use in Tortuga, renamed to linit.cpp -*/ - - -/* -** If you embed Lua in your program and need to open the standard -** libraries, call luaL_openlibs in your program. If you need a -** different set of libraries, copy this file to your project and edit -** it to suit your needs. -*/ - - #define linit_c #define LUA_LIB #include "lua/lua.hpp" + #include "region_api.hpp" +#include "pager_api.hpp" - -/* -** these libs are loaded by lua.c and are readily available to any Lua -** program -*/ +//these libs are loaded by lua.c and are readily available to any Lua program static const luaL_Reg loadedlibs[] = { - /* Standard libs */ - {"_G", luaopen_base}, - {LUA_LOADLIBNAME, luaopen_package}, - {LUA_COLIBNAME, luaopen_coroutine}, - {LUA_TABLIBNAME, luaopen_table}, - {LUA_IOLIBNAME, luaopen_io}, - {LUA_OSLIBNAME, luaopen_os}, - {LUA_STRLIBNAME, luaopen_string}, - {LUA_BITLIBNAME, luaopen_bit32}, - {LUA_MATHLIBNAME, luaopen_math}, - {LUA_DBLIBNAME, luaopen_debug}, + //Standard libs + {"_G", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_BITLIBNAME, luaopen_bit32}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, - /* custom libs */ - {LUA_REGIONLIBNAME, luaopen_regionapi}, + //custom libs + {LUA_REGIONLIBNAME, luaopen_regionapi}, + {LUA_PAGERLIBNAME, luaopen_pagerapi}, - {NULL, NULL} + {NULL, NULL} }; -/* -** these libs are preloaded and must be required before used -*/ +//these libs are preloaded and must be required before used static const luaL_Reg preloadedlibs[] = { - {NULL, NULL} + {NULL, NULL} }; - LUALIB_API void luaL_openlibs (lua_State *L) { - const luaL_Reg *lib; - /* call open functions from 'loadedlibs' and set results to global table */ - for (lib = loadedlibs; lib->func; lib++) { - luaL_requiref(L, lib->name, lib->func, 1); - lua_pop(L, 1); /* remove lib */ - } - /* add open functions from 'preloadedlibs' into 'package.preload' table */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); - for (lib = preloadedlibs; lib->func; lib++) { - lua_pushcfunction(L, lib->func); - lua_setfield(L, -2, lib->name); - } - lua_pop(L, 1); /* remove _PRELOAD table */ + const luaL_Reg *lib; + //call open functions from 'loadedlibs' and set results to global table + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); //remove lib + } + //add open functions from 'preloadedlibs' into 'package.preload' table + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + for (lib = preloadedlibs; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); + } + lua_pop(L, 1); //remove _PRELOAD table } \ No newline at end of file diff --git a/common/script/pager_api.cpp b/common/script/pager_api.cpp new file mode 100644 index 0000000..5e88260 --- /dev/null +++ b/common/script/pager_api.cpp @@ -0,0 +1,36 @@ +/* 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 "pager_api.hpp" + +static int func(lua_State* L) { + return 0; +} + +static const luaL_Reg pagerlib[] = { + {"name", func}, + {nullptr, nullptr} +}; + +LUAMOD_API int luaopen_pagerapi(lua_State* L) { + luaL_newlib(L, pagerlib); + return 1; +} \ No newline at end of file diff --git a/common/script/pager_api.hpp b/common/script/pager_api.hpp new file mode 100644 index 0000000..2531e94 --- /dev/null +++ b/common/script/pager_api.hpp @@ -0,0 +1,30 @@ +/* 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 PAGERAPI_HPP_ +#define PAGERAPI_HPP_ + +#include "lua/lua.hpp" + +#define LUA_PAGERLIBNAME "pager" +LUAMOD_API int luaopen_pagerapi(lua_State* L); + +#endif From b7c12ba1061963e71a2bc25d8939404ef2bd5ddb Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 10 Jun 2014 00:20:45 +1000 Subject: [PATCH 21/34] Fleshed out the pager's API --- common/map/region_pager.cpp | 25 ++++++++---- common/map/region_pager.hpp | 1 - common/script/pager_api.cpp | 73 +++++++++++++++++++++++++++++++++++- common/script/region_api.cpp | 65 +++++++++++++++++++++++--------- 4 files changed, 135 insertions(+), 29 deletions(-) diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp index 547b51f..098a720 100644 --- a/common/map/region_pager.cpp +++ b/common/map/region_pager.cpp @@ -70,10 +70,14 @@ Region* RegionPager::LoadRegion(int x, int y) { x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); - Region* ptr = new Region(x, y); + //overwrite? + Region* ptr = FindRegion(x, y); + if (!ptr) { + ptr = new Region(x, y); + } //API hook - lua_getglobal(luaState, "map"); + lua_getglobal(luaState, "region"); lua_getfield(luaState, -1, "load"); lua_pushlightuserdata(luaState, ptr); lua_pushstring(luaState, directory.c_str()); @@ -101,7 +105,7 @@ Region* RegionPager::SaveRegion(int x, int y) { Region* ptr = FindRegion(x, y); if (ptr) { //API hook - lua_getglobal(luaState, "map"); + lua_getglobal(luaState, "region"); lua_getfield(luaState, -1, "save"); lua_pushlightuserdata(luaState, ptr); lua_pushstring(luaState, directory.c_str()); @@ -118,13 +122,17 @@ Region* RegionPager::CreateRegion(int x, int y) { x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); - //create and push the object - Region* ptr = new Region(x, y); + //overwrite? + Region* ptr = FindRegion(x, y); + if (!ptr) { + ptr = new Region(x, y); + } //API hook - lua_getglobal(luaState, "map"); + lua_getglobal(luaState, "region"); lua_getfield(luaState, -1, "create"); lua_pushlightuserdata(luaState, ptr); + //TODO: parameters if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); } @@ -139,7 +147,7 @@ void RegionPager::UnloadRegion(int x, int y) { x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); - lua_getglobal(luaState, "map"); + lua_getglobal(luaState, "region"); //custom loop, not FindRegion() for (std::list::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) { @@ -148,7 +156,8 @@ void RegionPager::UnloadRegion(int x, int y) { //API hook lua_getfield(luaState, -1, "unload"); lua_pushlightuserdata(luaState, *it); - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); } diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index e53bc2c..ab119dc 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -46,7 +46,6 @@ public: Region* SaveRegion(int x, int y); Region* CreateRegion(int x, int y); void UnloadRegion(int x, int y); - void DeleteRegion(int x, int y); //accessors & mutators std::list* GetContainer() { return ®ionList; } diff --git a/common/script/pager_api.cpp b/common/script/pager_api.cpp index 5e88260..16c10dd 100644 --- a/common/script/pager_api.cpp +++ b/common/script/pager_api.cpp @@ -21,12 +21,81 @@ */ #include "pager_api.hpp" -static int func(lua_State* L) { +#include "region_pager.hpp" +#include "region.hpp" + +#include + +static int setTile(lua_State* L) { + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + int ret = pager->SetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); + lua_pop(L, 5); + lua_pushinteger(L, ret); + return 1; +} + +static int getTile(lua_State* L) { + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + int ret = pager->GetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); + lua_pop(L, 4); + lua_pushinteger(L, ret); + return 1; +} + +static int getRegion(lua_State* L) { + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); + lua_pop(L, 3); + lua_pushlightuserdata(L, region); + return 1; +} + +static int setDirectory(lua_State* L) { + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + std::string s = pager->SetDirectory(lua_tostring(L, 2)); + lua_pop(L, 2); + lua_pushstring(L, s.c_str()); + return 1; +} + +static int getDirectory(lua_State* L) { + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + std::string s = pager->GetDirectory(); + lua_pop(L, 1); + lua_pushstring(L, s.c_str()); + return 1; +} + +static int loadRegion(lua_State* L) { + //TODO: fill this + return 0; +} + +static int saveRegion(lua_State* L) { + //TODO: fill this + return 0; +} + +static int createRegion(lua_State* L) { + //TODO: fill this + return 0; +} + +static int unloadRegion(lua_State* L) { + //TODO: fill this return 0; } static const luaL_Reg pagerlib[] = { - {"name", func}, + {"settile", setTile}, + {"gettile", getTile}, + {"getregion", getRegion}, + {"setdirectory", setDirectory}, + {"getdirectory", getDirectory}, + {"loadregion", loadRegion}, + {"saveregion", saveRegion}, + {"createregion", createRegion}, + {"unloadregion", unloadRegion}, {nullptr, nullptr} }; diff --git a/common/script/region_api.cpp b/common/script/region_api.cpp index c94691b..9e16d45 100644 --- a/common/script/region_api.cpp +++ b/common/script/region_api.cpp @@ -24,55 +24,84 @@ #include "region.hpp" static int setTile(lua_State* L) { - //operating on a region - Region* ptr = (Region*)lua_touserdata(L, 1); - ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5)); - return 0; + Region* region = reinterpret_cast(lua_touserdata(L, 1)); + int ret = region->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5)); + lua_pop(L, 5); + lua_pushinteger(L, ret); + return 1; } static int getTile(lua_State* L) { - //operating on a region - Region* ptr = (Region*)lua_touserdata(L, 1); - int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1); - lua_pushnumber(L, ret); + Region* region = reinterpret_cast(lua_touserdata(L, 1)); + int ret = region->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1); + lua_pop(L, 4); + lua_pushinteger(L, ret); return 1; } static int getX(lua_State* L) { - Region* ptr = (Region*)lua_touserdata(L, 1); - lua_pushinteger(L, ptr->GetX()); + Region* region = reinterpret_cast(lua_touserdata(L, 1)); + int ret = region->GetX(); + lua_pop(L, 1); + lua_pushinteger(L, ret); return 1; } static int getY(lua_State* L) { - Region* ptr = (Region*)lua_touserdata(L, 1); - lua_pushinteger(L, ptr->GetY()); + Region* region = reinterpret_cast(lua_touserdata(L, 1)); + int ret = region->GetY(); + lua_pop(L, 1); + lua_pushinteger(L, ret); return 1; } -static int getRegionWidth(lua_State* L) { +static int getWidth(lua_State* L) { lua_pushinteger(L, REGION_WIDTH); return 1; } -static int getRegionHeight(lua_State* L) { +static int getHeight(lua_State* L) { lua_pushinteger(L, REGION_HEIGHT); return 1; } -static int getRegionDepth(lua_State* L) { +static int getDepth(lua_State* L) { lua_pushinteger(L, REGION_DEPTH); return 1; } +static int load(lua_State* L) { + //TODO: fill this + return 0; +} + +static int save(lua_State* L) { + //TODO: fill this + return 0; +} + +static int create(lua_State* L) { + //TODO: fill this + return 0; +} + +static int unload(lua_State* L) { + //TODO: fill this + return 0; +} + static const luaL_Reg regionlib[] = { {"settile",setTile}, {"gettile",getTile}, {"getx",getX}, {"gety",getY}, - {"getregionwidth",getRegionWidth}, - {"getregionheight",getRegionHeight}, - {"getregiondepth",getRegionDepth}, + {"getwidth",getWidth}, + {"getheight",getHeight}, + {"getdepth",getDepth}, + {"load",load}, + {"save",save}, + {"create",create}, + {"unload",unload}, {nullptr, nullptr} }; From 135e650ec8f7a79069af929f9a0d38753f026f96 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 10 Jun 2014 00:38:00 +1000 Subject: [PATCH 22/34] Moved the map API to the map directory --- common/makefile | 1 - common/{script => map}/pager_api.cpp | 0 common/{script => map}/pager_api.hpp | 0 common/{script => map}/region_api.cpp | 0 common/{script => map}/region_api.hpp | 0 common/script/makefile | 37 --------------------------- {common/script => server}/linit.cpp | 0 7 files changed, 38 deletions(-) rename common/{script => map}/pager_api.cpp (100%) rename common/{script => map}/pager_api.hpp (100%) rename common/{script => map}/region_api.cpp (100%) rename common/{script => map}/region_api.hpp (100%) delete mode 100644 common/script/makefile rename {common/script => server}/linit.cpp (100%) diff --git a/common/makefile b/common/makefile index 0e48688..b670b7d 100644 --- a/common/makefile +++ b/common/makefile @@ -3,7 +3,6 @@ all: $(MAKE) -C graphics $(MAKE) -C map $(MAKE) -C network - $(MAKE) -C script $(MAKE) -C ui $(MAKE) -C utilities diff --git a/common/script/pager_api.cpp b/common/map/pager_api.cpp similarity index 100% rename from common/script/pager_api.cpp rename to common/map/pager_api.cpp diff --git a/common/script/pager_api.hpp b/common/map/pager_api.hpp similarity index 100% rename from common/script/pager_api.hpp rename to common/map/pager_api.hpp diff --git a/common/script/region_api.cpp b/common/map/region_api.cpp similarity index 100% rename from common/script/region_api.cpp rename to common/map/region_api.cpp diff --git a/common/script/region_api.hpp b/common/map/region_api.hpp similarity index 100% rename from common/script/region_api.hpp rename to common/map/region_api.hpp diff --git a/common/script/makefile b/common/script/makefile deleted file mode 100644 index 7cab524..0000000 --- a/common/script/makefile +++ /dev/null @@ -1,37 +0,0 @@ -#config -INCLUDES+=. ../map ../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)/,libcommon.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/common/script/linit.cpp b/server/linit.cpp similarity index 100% rename from common/script/linit.cpp rename to server/linit.cpp From 1ef5eb7a0f31f9e3324d17f65f1e0c062f90d033 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 10 Jun 2014 00:52:19 +1000 Subject: [PATCH 23/34] Pager's heavyweight API methods call the Region's counterparts --- common/map/pager_api.cpp | 71 +++++++++++++++++++++++++++++++++------ common/map/region_api.cpp | 10 ++---- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/common/map/pager_api.cpp b/common/map/pager_api.cpp index 16c10dd..332cc5e 100644 --- a/common/map/pager_api.cpp +++ b/common/map/pager_api.cpp @@ -24,12 +24,12 @@ #include "region_pager.hpp" #include "region.hpp" +#include #include static int setTile(lua_State* L) { RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); int ret = pager->SetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); - lua_pop(L, 5); lua_pushinteger(L, ret); return 1; } @@ -37,7 +37,6 @@ static int setTile(lua_State* L) { static int getTile(lua_State* L) { RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); int ret = pager->GetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); - lua_pop(L, 4); lua_pushinteger(L, ret); return 1; } @@ -45,7 +44,6 @@ static int getTile(lua_State* L) { static int getRegion(lua_State* L) { RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); - lua_pop(L, 3); lua_pushlightuserdata(L, region); return 1; } @@ -53,7 +51,6 @@ static int getRegion(lua_State* L) { static int setDirectory(lua_State* L) { RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); std::string s = pager->SetDirectory(lua_tostring(L, 2)); - lua_pop(L, 2); lua_pushstring(L, s.c_str()); return 1; } @@ -61,28 +58,82 @@ static int setDirectory(lua_State* L) { static int getDirectory(lua_State* L) { RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); std::string s = pager->GetDirectory(); - lua_pop(L, 1); lua_pushstring(L, s.c_str()); return 1; } static int loadRegion(lua_State* L) { - //TODO: fill this - return 0; + //get the parameters + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); + std::string s = pager->GetDirectory(); + + //push the parameters + lua_getglobal(L, "region"); + lua_getfield(L, -1, "load"); + lua_pushlightuserdata(L, region); + lua_pushstring(L, s.c_str()); + + //call the method + if (lua_pcall(L, 2, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(L, -1) )); + } + return 1; } static int saveRegion(lua_State* L) { - //TODO: fill this + //get the parameters + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); + std::string s = pager->GetDirectory(); + + //push the parameters + lua_getglobal(L, "region"); + lua_getfield(L, -1, "save"); + lua_pushlightuserdata(L, region); + lua_pushstring(L, s.c_str()); + + //call the method + if (lua_pcall(L, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(L, -1) )); + } return 0; } static int createRegion(lua_State* L) { - //TODO: fill this + //get the parameters + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); + + //push the parameters + lua_getglobal(L, "region"); + lua_getfield(L, -1, "create"); + lua_pushlightuserdata(L, region); + //TODO: parameters + + //call the method + if (lua_pcall(L, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(L, -1) )); + } return 0; } static int unloadRegion(lua_State* L) { - //TODO: fill this + //get the parameters + RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); + std::string s = pager->GetDirectory(); + + //push the parameters + lua_getglobal(L, "region"); + lua_getfield(L, -1, "unload"); + lua_pushlightuserdata(L, region); + lua_pushstring(L, s.c_str()); + + //call the method + if (lua_pcall(L, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(L, -1) )); + } return 0; } diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index 9e16d45..df37532 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -26,7 +26,6 @@ static int setTile(lua_State* L) { Region* region = reinterpret_cast(lua_touserdata(L, 1)); int ret = region->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5)); - lua_pop(L, 5); lua_pushinteger(L, ret); return 1; } @@ -34,24 +33,19 @@ static int setTile(lua_State* L) { static int getTile(lua_State* L) { Region* region = reinterpret_cast(lua_touserdata(L, 1)); int ret = region->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1); - lua_pop(L, 4); lua_pushinteger(L, ret); return 1; } static int getX(lua_State* L) { Region* region = reinterpret_cast(lua_touserdata(L, 1)); - int ret = region->GetX(); - lua_pop(L, 1); - lua_pushinteger(L, ret); + lua_pushinteger(L, region->GetX()); return 1; } static int getY(lua_State* L) { Region* region = reinterpret_cast(lua_touserdata(L, 1)); - int ret = region->GetY(); - lua_pop(L, 1); - lua_pushinteger(L, ret); + lua_pushinteger(L, region->GetY()); return 1; } From a07e7418a6c36ed085f34238b5664353f3a4b98f Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 10 Jun 2014 01:46:42 +1000 Subject: [PATCH 24/34] Implemented a basic API for the server's rooms --- common/map/region_api.cpp | 3 +- rsc/scripts/setup_server.lua | 34 +++++-------------- server/makefile | 2 +- server/room_api.cpp | 63 +++++++++++++++++++++++++++++++++++ server/room_api.hpp | 30 +++++++++++++++++ server/room_manager.hpp | 4 ++- server/server_application.cpp | 22 ++++++------ 7 files changed, 119 insertions(+), 39 deletions(-) create mode 100644 server/room_api.cpp create mode 100644 server/room_api.hpp diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index df37532..b30f04f 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -66,7 +66,8 @@ static int getDepth(lua_State* L) { static int load(lua_State* L) { //TODO: fill this - return 0; + lua_pushboolean(L, false); + return 1; } static int save(lua_State* L) { diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 8629320..bae4a74 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -4,33 +4,17 @@ print("Lua script check (./rsc)") --Map API overrides ------------------------- -function map.create(region) - for i = 1, map.getregionwidth() do - for j = 1, map.getregionheight() do - if math.abs(map.getx(region) + i -1) == math.abs(map.gety(region) + j -1) then - map.settile(region, i, j, 1, 50) +function region.create(r) + for i = 1, region.getwidth() do + for j = 1, region.getheight() do + if math.abs(region.getx(r) + i -1) == math.abs(region.gety(r) + j -1) then + region.settile(r, i, j, 1, 50) else - map.settile(region, i, j, 1, 14) + region.settile(r, i, j, 1, 14) end end end + + --signal + region.settile(r, 4, 5, 2, 86) end - -function map.unload(region) - -- -end - -function map.load(region, dir) - --return true if file loaded, otherwise return false - return false -end - -function map.save(region, dir) - -- -end - -------------------------- ---Enemy API -------------------------- - ---TODO \ No newline at end of file diff --git a/server/makefile b/server/makefile index 7c733ea..1d8df31 100644 --- a/server/makefile +++ b/server/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/script ../common/utilities +INCLUDES+=. ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/room_api.cpp b/server/room_api.cpp new file mode 100644 index 0000000..ea7ea52 --- /dev/null +++ b/server/room_api.cpp @@ -0,0 +1,63 @@ +/* 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 "room_api.hpp" + +#include "room_manager.hpp" +#include "room_data.hpp" + +static int getType(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, static_cast(room->type)); + return 1; +} + +//TODO: parameters + +static int getRegionPager(lua_State* L) { + RoomData* room = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushlightuserdata(L, reinterpret_cast(&room->pager)); + return 1; +} + +//RoomManager only +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)) )); + return 1; +} + +static const luaL_Reg roomlib[] = { + {"gettype",getType}, + {"getregionpager",getRegionPager}, + {"getroom",getRoom}, + {nullptr, nullptr} +}; + +LUAMOD_API int luaopen_roomapi(lua_State* L) { + luaL_newlib(L, roomlib); + return 1; +} \ No newline at end of file diff --git a/server/room_api.hpp b/server/room_api.hpp new file mode 100644 index 0000000..a9c31a8 --- /dev/null +++ b/server/room_api.hpp @@ -0,0 +1,30 @@ +/* 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 ROOMAPI_HPP_ +#define ROOMAPI_HPP_ + +#include "lua/lua.hpp" + +#define LUA_ROOMLIBNAME "room" +LUAMOD_API int luaopen_roomapi(lua_State* L); + +#endif diff --git a/server/room_manager.hpp b/server/room_manager.hpp index 9b1dfc6..655c960 100644 --- a/server/room_manager.hpp +++ b/server/room_manager.hpp @@ -28,13 +28,15 @@ #include +#define ROOM_MANAGER_PSEUDOINDEX "RoomManager" + class RoomManager { public: RoomManager() = default; ~RoomManager() = default; //public access methods - //TODO + //TODO: Fill this out //accessors and mutators RoomData* GetRoom(int uid); diff --git a/server/server_application.cpp b/server/server_application.cpp index 0cb011d..6fd85d9 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -76,6 +76,7 @@ void ServerApplication::Init(int argc, char** argv) { //Setup the objects //------------------------- + //set the hooks accountMgr.SetDatabase(database); characterMgr.SetDatabase(database); @@ -83,7 +84,14 @@ void ServerApplication::Init(int argc, char** argv) { roomMgr.SetLuaState(luaState); enemyMgr.SetLuaState(luaState); - std::cout << "Internal managers ready" << std::endl; + 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 @@ -110,6 +118,7 @@ void ServerApplication::Init(int argc, char** argv) { std::cout << "\tRegion Format: " << REGION_WIDTH << ", " << REGION_HEIGHT << ", " << REGION_DEPTH << std::endl; std::cout << "\tRegion Content Footprint: " << REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) << std::endl; std::cout << "\tPACKET_BUFFER_SIZE (max size): " << PACKET_BUFFER_SIZE << std::endl; + std::cout << "\tMAX_PACKET_SIZE: " << MAX_PACKET_SIZE << std::endl; //------------------------- //finalize the startup @@ -121,16 +130,7 @@ void ServerApplication::Init(int argc, char** argv) { //debugging //------------------------- - std::cout << "Debugging dump:" << std::endl; - std::cout << "\tMAX_PACKET_SIZE:\t\t" << MAX_PACKET_SIZE << std::endl; - std::cout << "\tsizeof(SerialPacket):\t\t" << sizeof(SerialPacket) << std::endl; - std::cout << "\tsizeof(CharacterPacket):\t" << sizeof(CharacterPacket) << std::endl; - std::cout << "\t\tsizeof(Statistics):\t" << sizeof(Statistics) << std::endl; - std::cout << "\tsizeof(ClientPacket):\t\t" << sizeof(ClientPacket) << std::endl; - std::cout << "\tsizeof(CombatPacket):\t\t" << sizeof(CombatPacket) << std::endl; - std::cout << "\tsizeof(EnemyPacket):\t\t" << sizeof(EnemyPacket) << std::endl; - std::cout << "\tsizeof(RegionPacket):\t\t" << sizeof(RegionPacket) << std::endl; - std::cout << "\tsizeof(ServerPacket):\t\t" << sizeof(ServerPacket) << std::endl; + //... } void ServerApplication::Proc() { From ee79231de066cbf9e4716619bc6192055b8d4917 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 10 Jun 2014 02:42:07 +1000 Subject: [PATCH 25/34] Began bringing the client into line with the server's changes Several parts of the client already built correctly. Updated LobbyMenu, it not builds. --- client/client_application.cpp | 2 +- client/in_world.hpp | 4 +- client/lobby_menu.cpp | 78 ++++++++++---------- client/lobby_menu.hpp | 16 ++-- common/map/region_pager.cpp | 20 +++++ common/map/region_pager.hpp | 1 + common/network/packet/serial_packet_base.hpp | 2 - 7 files changed, 72 insertions(+), 51 deletions(-) diff --git a/client/client_application.cpp b/client/client_application.cpp index b9a31bd..d3ce86c 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -124,7 +124,7 @@ void ClientApplication::LoadScene(SceneList sceneIndex) { activeScene = new OptionsMenu(&config); break; case SceneList::LOBBYMENU: - activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex, &characterIndex); + activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex); break; case SceneList::INWORLD: activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap); diff --git a/client/in_world.hpp b/client/in_world.hpp index 038d22c..f993fc6 100644 --- a/client/in_world.hpp +++ b/client/in_world.hpp @@ -23,8 +23,6 @@ #define INWORLD_HPP_ //maps -#include "map_allocator.hpp" -#include "map_file_format.hpp" #include "region_pager.hpp" //networking @@ -112,7 +110,7 @@ protected: TileSheet tileSheet; //map - RegionPager regionPager; + RegionPager regionPager; //UI Button disconnectButton; diff --git a/client/lobby_menu.cpp b/client/lobby_menu.cpp index ddc6998..3056db3 100644 --- a/client/lobby_menu.cpp +++ b/client/lobby_menu.cpp @@ -34,14 +34,12 @@ LobbyMenu::LobbyMenu( ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, - int* const argAccountIndex, - int* const argCharacterIndex + int* const argAccountIndex ): config(*argConfig), network(*argNetwork), clientIndex(*argClientIndex), - accountIndex(*argAccountIndex), - characterIndex(*argCharacterIndex) + accountIndex(*argAccountIndex) { //setup the utility objects image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); @@ -87,9 +85,9 @@ void LobbyMenu::FrameStart() { void LobbyMenu::Update(double delta) { //suck in and process all waiting packets - SerialPacket packet; - while(network.Receive(&packet)) { - HandlePacket(packet); + char packetBuffer[MAX_PACKET_SIZE]; + while(network.Receive(reinterpret_cast(packetBuffer))) { + HandlePacket(reinterpret_cast(packetBuffer)); } } @@ -149,7 +147,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { if (search.MouseButtonUp(button) == Button::State::HOVER) { //broadcast to the network, or a specific server SerialPacket packet; - packet.meta.type = SerialPacket::Type::BROADCAST_REQUEST; + packet.type = SerialPacketType::BROADCAST_REQUEST; network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet); //reset the server list @@ -159,11 +157,9 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr && selection->compatible) { //pack the packet - SerialPacket packet; - packet.meta.type = SerialPacket::Type::JOIN_REQUEST; - strncpy(packet.clientInfo.username, config["client.username"].c_str(), PACKET_STRING_SIZE); - strncpy(packet.clientInfo.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE); - strncpy(packet.clientInfo.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE); + ClientPacket packet; + packet.type = SerialPacketType::JOIN_REQUEST; + strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE); //join the selected server network.SendTo(&selection->address, &packet); @@ -176,6 +172,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { else if ( //has the user selected a server on the list? + //TODO: replace with regular collision checker button.x > listBox.x && button.x < listBox.x + listBox.w && button.y > listBox.y && @@ -204,34 +201,41 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) { //Network handlers //------------------------- -void LobbyMenu::HandlePacket(SerialPacket packet) { - switch(packet.meta.type) { - case SerialPacket::Type::BROADCAST_RESPONSE: { - //extract the data - ServerInformation server; - server.address = packet.meta.srcAddress; - server.networkVersion = packet.serverInfo.networkVersion; - server.name = packet.serverInfo.name; - server.playerCount = packet.serverInfo.playerCount; - - //NOTE: Check compatibility here - server.compatible = server.networkVersion == NETWORK_VERSION; - - //push - serverInfo.push_back(server); - } +void LobbyMenu::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { + case SerialPacketType::BROADCAST_RESPONSE: + HandleBroadcastResponse(dynamic_cast(argPacket)); break; - case SerialPacket::Type::JOIN_RESPONSE: - clientIndex = packet.clientInfo.clientIndex; - accountIndex = packet.clientInfo.accountIndex; - characterIndex = packet.clientInfo.characterIndex; - network.Bind(&packet.meta.srcAddress, Channels::SERVER); - SetNextScene(SceneList::INWORLD); + case SerialPacketType::JOIN_RESPONSE: + HandleJoinResponse(dynamic_cast(argPacket)); break; - //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(int(packet.meta.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(static_cast(argPacket->type)) )); break; } +} + +void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) { + //extract the data + ServerInformation server; + server.address = argPacket->srcAddress; + server.name = argPacket->name; + server.playerCount = argPacket->playerCount; + server.version = argPacket->version; + + //NOTE: Check compatibility here + server.compatible = server.version == NETWORK_VERSION; + + //push + serverInfo.push_back(server); +} + +void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) { + clientIndex = argPacket->clientIndex; + accountIndex = argPacket->accountIndex; + network.Bind(&argPacket->srcAddress, Channels::SERVER); + SetNextScene(SceneList::INWORLD); + + //TODO: send this player's character info } \ No newline at end of file diff --git a/client/lobby_menu.hpp b/client/lobby_menu.hpp index 2360705..a27c1a9 100644 --- a/client/lobby_menu.hpp +++ b/client/lobby_menu.hpp @@ -22,13 +22,13 @@ #ifndef LOBBYMENU_HPP_ #define LOBBYMENU_HPP_ -//graphics & utilities +//graphics & ui #include "image.hpp" #include "raster_font.hpp" #include "button.hpp" -#include "config_utility.hpp" -//network +//utilities +#include "config_utility.hpp" #include "udp_network_utility.hpp" //client @@ -44,8 +44,7 @@ public: ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex, - int* const argAccountIndex, - int* const argCharacterIndex + int* const argAccountIndex ); ~LobbyMenu(); @@ -64,14 +63,15 @@ protected: void KeyUp(SDL_KeyboardEvent const&); //Network handlers - void HandlePacket(SerialPacket); + void HandlePacket(SerialPacket* const); + void HandleBroadcastResponse(ServerPacket* const); + void HandleJoinResponse(ClientPacket* const); //shared parameters ConfigUtility& config; UDPNetworkUtility& network; int& clientIndex; int& accountIndex; - int& characterIndex; //members Image image; @@ -83,9 +83,9 @@ protected: //server list struct ServerInformation { IPaddress address; - int networkVersion; std::string name; int playerCount; + int version; bool compatible; }; diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp index 098a720..9a4e780 100644 --- a/common/map/region_pager.cpp +++ b/common/map/region_pager.cpp @@ -64,6 +64,11 @@ Region* RegionPager::FindRegion(int x, int y) { } Region* RegionPager::LoadRegion(int x, int y) { + //only work if using lua + if (!luaState) { + throw(std::runtime_error("RegionPager::luaState is null")); + } + //load the region if possible //snap the coords @@ -97,6 +102,11 @@ Region* RegionPager::LoadRegion(int x, int y) { } Region* RegionPager::SaveRegion(int x, int y) { + //only work if using lua + if (!luaState) { + throw(std::runtime_error("RegionPager::luaState is null")); + } + //snap the coords x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); @@ -118,6 +128,11 @@ Region* RegionPager::SaveRegion(int x, int y) { } Region* RegionPager::CreateRegion(int x, int y) { + //only work if using lua + if (!luaState) { + throw(std::runtime_error("RegionPager::luaState is null")); + } + //snap the coords x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); @@ -143,6 +158,11 @@ Region* RegionPager::CreateRegion(int x, int y) { } void RegionPager::UnloadRegion(int x, int y) { + //only work if using lua + if (!luaState) { + throw(std::runtime_error("RegionPager::luaState is null")); + } + //snap the coords x = snapToBase(REGION_WIDTH, x); y = snapToBase(REGION_HEIGHT, y); diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index ab119dc..a4d26ab 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -29,6 +29,7 @@ #include #include +//TODO: split this into two: "RegionPagerBase" and "RegionPagerLua" class RegionPager { public: RegionPager() = default; diff --git a/common/network/packet/serial_packet_base.hpp b/common/network/packet/serial_packet_base.hpp index 760e54a..b84816e 100644 --- a/common/network/packet/serial_packet_base.hpp +++ b/common/network/packet/serial_packet_base.hpp @@ -38,8 +38,6 @@ struct SerialPacketBase { SerialPacketType type; IPaddress srcAddress; - typedef SerialPacketType Type; - virtual ~SerialPacketBase() {}; }; From 955aed22241b4994d9fe34139e40050140388dda Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 11 Jun 2014 21:48:01 +1000 Subject: [PATCH 26/34] in_world.cpp is building --- client/in_world.cpp | 178 +++++++++++++++++++----------------- client/in_world.hpp | 14 +-- common/map/region_pager.cpp | 13 +++ common/map/region_pager.hpp | 1 + 4 files changed, 114 insertions(+), 92 deletions(-) diff --git a/client/in_world.cpp b/client/in_world.cpp index 6aa6a5a..dd739e5 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -22,6 +22,7 @@ #include "in_world.hpp" #include "channels.hpp" +#include "utility.hpp" #include #include @@ -93,11 +94,10 @@ void InWorld::FrameStart() { } void InWorld::Update(double delta) { - SerialPacket packet; - - //suck in all waiting packets - while(network.Receive(&packet)) { - HandlePacket(packet); + //suck in and process all waiting packets + char packetBuffer[MAX_PACKET_SIZE]; + while(network.Receive(reinterpret_cast(packetBuffer))) { + HandlePacket(reinterpret_cast(packetBuffer)); } //update the characters @@ -248,76 +248,55 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { //Network handlers //------------------------- -void InWorld::HandlePacket(SerialPacket packet) { - switch(packet.meta.type) { - case SerialPacket::Type::DISCONNECT: - HandleDisconnect(packet); +void InWorld::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { + case SerialPacketType::DISCONNECT: + HandleDisconnect(argPacket); break; - case SerialPacket::Type::REGION_CONTENT: - HandleRegionContent(packet); + case SerialPacketType::CHARACTER_NEW: + HandleCharacterNew(dynamic_cast(argPacket)); break; - case SerialPacket::Type::CHARACTER_UPDATE: - HandleCharacterUpdate(packet); + case SerialPacketType::CHARACTER_DELETE: + HandleCharacterDelete(dynamic_cast(argPacket)); break; - case SerialPacket::Type::CHARACTER_NEW: - HandleCharacterNew(packet); + case SerialPacketType::CHARACTER_UPDATE: + HandleCharacterUpdate(dynamic_cast(argPacket)); break; - case SerialPacket::Type::CHARACTER_DELETE: - HandleCharacterDelete(packet); + case SerialPacketType::REGION_CONTENT: + HandleRegionContent(dynamic_cast(argPacket)); break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(int(packet.meta.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(int(argPacket->type)) )); break; } } -void InWorld::HandleDisconnect(SerialPacket packet) { +void InWorld::HandleDisconnect(SerialPacket* const argPacket) { SetNextScene(SceneList::RESTART); } -void InWorld::HandleRegionContent(SerialPacket packet) { - //replace existing regions - regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y); - regionPager.PushRegion(packet.regionInfo.region); - packet.regionInfo.region = nullptr; -} - -void InWorld::HandleCharacterUpdate(SerialPacket packet) { - if (characterMap.find(packet.characterInfo.characterIndex) == characterMap.end()) { - HandleCharacterNew(packet); - return; - } - - //update only if the message didn't originate from here - if (packet.characterInfo.clientIndex != clientIndex) { - characterMap[packet.characterInfo.characterIndex].origin = packet.characterInfo.origin; - characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion; - } - characterMap[packet.characterInfo.characterIndex].CorrectSprite(); -} - -void InWorld::HandleCharacterNew(SerialPacket packet) { - if (characterMap.find(packet.characterInfo.characterIndex) != characterMap.end()) { +void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { + if (characterMap.find(argPacket->characterIndex) != characterMap.end()) { throw(std::runtime_error("Cannot create duplicate characters")); } //create the character object - CharacterData& character = characterMap[packet.characterInfo.characterIndex]; + CharacterData& character = characterMap[argPacket->characterIndex]; //set the members - character.handle = packet.characterInfo.handle; - character.avatar = packet.characterInfo.avatar; + character.handle = argPacket->handle; + character.avatar = argPacket->avatar; character.sprite.LoadSurface(config["dir.sprites"] + character.avatar, 4, 4); - character.mapIndex = packet.characterInfo.mapIndex; - character.origin = packet.characterInfo.origin; - character.motion = packet.characterInfo.motion; - character.stats = packet.characterInfo.stats; + character.roomIndex = argPacket->roomIndex; + character.origin = argPacket->origin; + character.motion = argPacket->motion; + character.stats = argPacket->stats; character.CorrectSprite(); //catch this client's player object - if (packet.characterInfo.characterIndex == characterIndex && !localCharacter) { + if (argPacket->characterIndex == characterIndex && !localCharacter) { localCharacter = &character; //setup the camera @@ -331,15 +310,39 @@ void InWorld::HandleCharacterNew(SerialPacket packet) { } } -void InWorld::HandleCharacterDelete(SerialPacket packet) { +void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { //TODO: authenticate when own character is being deleted (linked to a TODO in the server) //catch this client's player object - if (packet.characterInfo.characterIndex == characterIndex) { + if (argPacket->characterIndex == characterIndex) { characterIndex = -1; localCharacter = nullptr; } - characterMap.erase(packet.characterInfo.characterIndex); + characterMap.erase(argPacket->characterIndex); +} + +void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) { + if (characterMap.find(argPacket->characterIndex) == characterMap.end()) { + HandleCharacterNew(argPacket); + return; + } + + CharacterData& character = characterMap[argPacket->characterIndex]; + + //TODO: review this + if (argPacket->characterIndex != characterIndex) { + character.roomIndex = argPacket->roomIndex; + character.origin = argPacket->origin; + character.motion = argPacket->motion; + character.CorrectSprite(); + } +} + +void InWorld::HandleRegionContent(RegionPacket* const argPacket) { + //replace existing regions + regionPager.UnloadRegion(argPacket->x, argPacket->y); + regionPager.PushRegion(argPacket->region); + argPacket->region = nullptr; } //------------------------- @@ -347,63 +350,68 @@ void InWorld::HandleCharacterDelete(SerialPacket packet) { //------------------------- void InWorld::RequestSynchronize() { - SerialPacket packet; + ClientPacket newPacket; //request a sync - packet.meta.type = SerialPacket::Type::SYNCHRONIZE; - packet.clientInfo.clientIndex = clientIndex; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + newPacket.type = SerialPacketType::SYNCHRONIZE; + newPacket.clientIndex = clientIndex; + newPacket.accountIndex = accountIndex; - network.SendTo(Channels::SERVER, &packet); + network.SendTo(Channels::SERVER, &newPacket); } void InWorld::SendPlayerUpdate() { - SerialPacket packet; + CharacterPacket newPacket; //pack the packet - packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE; - packet.characterInfo.clientIndex = clientIndex; - packet.characterInfo.accountIndex = accountIndex; - packet.characterInfo.characterIndex = characterIndex; - packet.characterInfo.origin = localCharacter->origin; - packet.characterInfo.motion = localCharacter->motion; + newPacket.type = SerialPacketType::CHARACTER_UPDATE; - network.SendTo(Channels::SERVER, &packet); + newPacket.characterIndex = characterIndex; + //handle, avatar + newPacket.accountIndex = accountIndex; + newPacket.roomIndex = localCharacter->roomIndex; + newPacket.origin = localCharacter->origin; + newPacket.motion = localCharacter->motion; + newPacket.stats = localCharacter->stats; + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs + + network.SendTo(Channels::SERVER, &newPacket); } void InWorld::RequestDisconnect() { - SerialPacket packet; + ClientPacket newPacket; //send a disconnect request - packet.meta.type = SerialPacket::Type::DISCONNECT; - packet.clientInfo.clientIndex = clientIndex; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + newPacket.type = SerialPacketType::DISCONNECT; + newPacket.clientIndex = clientIndex; + newPacket.accountIndex = accountIndex; - network.SendTo(Channels::SERVER, &packet); + network.SendTo(Channels::SERVER, &newPacket); } void InWorld::RequestShutDown() { - SerialPacket packet; + ClientPacket newPacket; //send a shutdown request - packet.meta.type = SerialPacket::Type::SHUTDOWN; - packet.clientInfo.clientIndex = clientIndex; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + newPacket.type = SerialPacketType::SHUTDOWN; + newPacket.clientIndex = clientIndex; + newPacket.accountIndex = accountIndex; - network.SendTo(Channels::SERVER, &packet); + network.SendTo(Channels::SERVER, &newPacket); } -void InWorld::RequestRegion(int mapIndex, int x, int y) { - SerialPacket packet; +void InWorld::RequestRegion(int roomIndex, int x, int y) { + RegionPacket packet; //pack the region's data - packet.meta.type = SerialPacket::Type::REGION_REQUEST; - packet.regionInfo.mapIndex = mapIndex; - packet.regionInfo.x = x; - packet.regionInfo.y = y; + packet.type = SerialPacketType::REGION_REQUEST; + packet.roomIndex = roomIndex; + packet.x = x; + packet.y = y; network.SendTo(Channels::SERVER, &packet); } diff --git a/client/in_world.hpp b/client/in_world.hpp index f993fc6..526c72a 100644 --- a/client/in_world.hpp +++ b/client/in_world.hpp @@ -78,19 +78,19 @@ protected: void KeyUp(SDL_KeyboardEvent const&); //Network handlers - void HandlePacket(SerialPacket); - void HandleDisconnect(SerialPacket); - void HandleCharacterNew(SerialPacket); - void HandleCharacterDelete(SerialPacket); - void HandleCharacterUpdate(SerialPacket); - void HandleRegionContent(SerialPacket); + void HandlePacket(SerialPacket* const); + void HandleDisconnect(SerialPacket* const); + void HandleCharacterNew(CharacterPacket* const); + void HandleCharacterDelete(CharacterPacket* const); + void HandleCharacterUpdate(CharacterPacket* const); + void HandleRegionContent(RegionPacket* const); //Server control void RequestSynchronize(); void SendPlayerUpdate(); void RequestDisconnect(); void RequestShutDown(); - void RequestRegion(int mapIndex, int x, int y); + void RequestRegion(int roomIndex, int x, int y); //utilities void UpdateMap(); diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp index 9a4e780..e9e9b1c 100644 --- a/common/map/region_pager.cpp +++ b/common/map/region_pager.cpp @@ -63,6 +63,19 @@ Region* RegionPager::FindRegion(int x, int y) { return nullptr; } +Region* RegionPager::PushRegion(Region* const region) { + if ( + region->GetX() != snapToBase(REGION_WIDTH, region->GetX()) || + region->GetY() != snapToBase(REGION_HEIGHT, region->GetY()) + ) + { + throw(std::runtime_error("Pushed region does not conform to the region grid")); + } + + regionList.push_front(region); + return regionList.front(); +} + Region* RegionPager::LoadRegion(int x, int y) { //only work if using lua if (!luaState) { diff --git a/common/map/region_pager.hpp b/common/map/region_pager.hpp index a4d26ab..06ead7c 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager.hpp @@ -42,6 +42,7 @@ public: //region manipulation Region* GetRegion(int x, int y); Region* FindRegion(int x, int y); + Region* PushRegion(Region* const); Region* LoadRegion(int x, int y); Region* SaveRegion(int x, int y); From 13332bf3fc569f6a37a4651526f4a484d44a55b9 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 11 Jun 2014 21:57:34 +1000 Subject: [PATCH 27/34] in_combat.cpp builds; entire repo builds Doesn't mean I'm done yet. --- client/in_combat.cpp | 79 +++++++++++++++++++++++--------------------- client/in_combat.hpp | 4 +-- client/in_world.cpp | 2 +- 3 files changed, 44 insertions(+), 41 deletions(-) diff --git a/client/in_combat.cpp b/client/in_combat.cpp index 207b97e..b10164f 100644 --- a/client/in_combat.cpp +++ b/client/in_combat.cpp @@ -85,11 +85,10 @@ void InCombat::FrameStart() { } void InCombat::Update(double delta) { - SerialPacket packet; - - //suck in all waiting packets - while(network.Receive(&packet)) { - HandlePacket(packet); + //suck in and process all waiting packets + char packetBuffer[MAX_PACKET_SIZE]; + while(network.Receive(reinterpret_cast(packetBuffer))) { + HandlePacket(reinterpret_cast(packetBuffer)); } //TODO: more @@ -154,19 +153,19 @@ void InCombat::KeyUp(SDL_KeyboardEvent const& key) { //Network handlers //------------------------- -void InCombat::HandlePacket(SerialPacket packet) { - switch(packet.meta.type) { - case SerialPacket::Type::DISCONNECT: - HandleDisconnect(packet); +void InCombat::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { + case SerialPacketType::DISCONNECT: + HandleDisconnect(argPacket); break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InCombat: " + to_string_custom(int(packet.meta.type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InCombat: " + to_string_custom(static_cast(argPacket->type)) )); break; } } -void InCombat::HandleDisconnect(SerialPacket) { +void InCombat::HandleDisconnect(SerialPacket* const) { SetNextScene(SceneList::RESTART); } @@ -177,52 +176,56 @@ void InCombat::HandleDisconnect(SerialPacket) { //------------------------- void InCombat::RequestSynchronize() { - SerialPacket packet; + ClientPacket newPacket; //request a sync - packet.meta.type = SerialPacket::Type::SYNCHRONIZE; - packet.clientInfo.clientIndex = clientIndex; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + newPacket.type = SerialPacketType::SYNCHRONIZE; + newPacket.clientIndex = clientIndex; + newPacket.accountIndex = accountIndex; - network.SendTo(Channels::SERVER, &packet); + network.SendTo(Channels::SERVER, &newPacket); } void InCombat::SendPlayerUpdate() { - SerialPacket packet; + CharacterPacket newPacket; //pack the packet - packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE; - packet.characterInfo.clientIndex = clientIndex; - packet.characterInfo.accountIndex = accountIndex; - packet.characterInfo.characterIndex = characterIndex; -// packet.characterInfo.position = localCharacter->position; -// packet.characterInfo.motion = localCharacter->motion; - //TODO: stats + newPacket.type = SerialPacketType::CHARACTER_UPDATE; - network.SendTo(Channels::SERVER, &packet); + newPacket.characterIndex = characterIndex; + //handle, avatar + newPacket.accountIndex = accountIndex; +// newPacket.roomIndex = localCharacter->roomIndex; +// newPacket.origin = localCharacter->origin; +// newPacket.motion = localCharacter->motion; +// newPacket.stats = localCharacter->stats; + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs + + network.SendTo(Channels::SERVER, &newPacket); } void InCombat::RequestDisconnect() { - SerialPacket packet; + ClientPacket newPacket; //send a disconnect request - packet.meta.type = SerialPacket::Type::DISCONNECT; - packet.clientInfo.clientIndex = clientIndex; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + newPacket.type = SerialPacketType::DISCONNECT; + newPacket.clientIndex = clientIndex; + newPacket.accountIndex = accountIndex; - network.SendTo(Channels::SERVER, &packet); + network.SendTo(Channels::SERVER, &newPacket); } void InCombat::RequestShutdown() { - SerialPacket packet; + ClientPacket newPacket; //send a shutdown request - packet.meta.type = SerialPacket::Type::SHUTDOWN; - packet.clientInfo.clientIndex = clientIndex; - packet.clientInfo.accountIndex = accountIndex; - packet.clientInfo.characterIndex = characterIndex; + newPacket.type = SerialPacketType::SHUTDOWN; + newPacket.clientIndex = clientIndex; + newPacket.accountIndex = accountIndex; - network.SendTo(Channels::SERVER, &packet); + network.SendTo(Channels::SERVER, &newPacket); } diff --git a/client/in_combat.hpp b/client/in_combat.hpp index ea8dad1..d345037 100644 --- a/client/in_combat.hpp +++ b/client/in_combat.hpp @@ -73,8 +73,8 @@ protected: void KeyUp(SDL_KeyboardEvent const&); //Network handlers - void HandlePacket(SerialPacket); - void HandleDisconnect(SerialPacket); + void HandlePacket(SerialPacket* const); + void HandleDisconnect(SerialPacket* const); //TODO: more network handlers //Server control diff --git a/client/in_world.cpp b/client/in_world.cpp index dd739e5..3aadc51 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -267,7 +267,7 @@ void InWorld::HandlePacket(SerialPacket* const argPacket) { break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(int(argPacket->type)) )); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(static_cast(argPacket->type)) )); break; } } From a11867126c7f13bef92fd5e19e1a16d4da1f367c Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 12 Jun 2014 03:47:49 +1000 Subject: [PATCH 28/34] Fixed segfault in common, changed casting of packets to static_cast This required that I switch from using a char array for the packet buffers to using malloc() and free(). They make more sense anyway, and I've learned (or relearned) something about casting. --- client/in_combat.cpp | 7 ++- client/in_world.cpp | 15 ++--- client/lobby_menu.cpp | 11 ++-- common/network/packet/serial_packet_type.hpp | 64 ++++++++++---------- common/network/serial/serial.cpp | 28 ++++----- makefile | 3 +- server/server_application.cpp | 39 ++++++------ 7 files changed, 85 insertions(+), 82 deletions(-) diff --git a/client/in_combat.cpp b/client/in_combat.cpp index b10164f..24b85e9 100644 --- a/client/in_combat.cpp +++ b/client/in_combat.cpp @@ -86,10 +86,11 @@ void InCombat::FrameStart() { void InCombat::Update(double delta) { //suck in and process all waiting packets - char packetBuffer[MAX_PACKET_SIZE]; - while(network.Receive(reinterpret_cast(packetBuffer))) { - HandlePacket(reinterpret_cast(packetBuffer)); + SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); + while(network.Receive(packetBuffer)) { + HandlePacket(packetBuffer); } + free(static_cast(packetBuffer)); //TODO: more } diff --git a/client/in_world.cpp b/client/in_world.cpp index 3aadc51..9779a71 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -95,10 +95,11 @@ void InWorld::FrameStart() { void InWorld::Update(double delta) { //suck in and process all waiting packets - char packetBuffer[MAX_PACKET_SIZE]; - while(network.Receive(reinterpret_cast(packetBuffer))) { - HandlePacket(reinterpret_cast(packetBuffer)); + SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); + while(network.Receive(packetBuffer)) { + HandlePacket(packetBuffer); } + free(static_cast(packetBuffer)); //update the characters for (auto& it : characterMap) { @@ -254,16 +255,16 @@ void InWorld::HandlePacket(SerialPacket* const argPacket) { HandleDisconnect(argPacket); break; case SerialPacketType::CHARACTER_NEW: - HandleCharacterNew(dynamic_cast(argPacket)); + HandleCharacterNew(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(dynamic_cast(argPacket)); + HandleCharacterDelete(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_UPDATE: - HandleCharacterUpdate(dynamic_cast(argPacket)); + HandleCharacterUpdate(static_cast(argPacket)); break; case SerialPacketType::REGION_CONTENT: - HandleRegionContent(dynamic_cast(argPacket)); + HandleRegionContent(static_cast(argPacket)); break; //handle errors default: diff --git a/client/lobby_menu.cpp b/client/lobby_menu.cpp index 3056db3..facfa9f 100644 --- a/client/lobby_menu.cpp +++ b/client/lobby_menu.cpp @@ -85,10 +85,11 @@ void LobbyMenu::FrameStart() { void LobbyMenu::Update(double delta) { //suck in and process all waiting packets - char packetBuffer[MAX_PACKET_SIZE]; - while(network.Receive(reinterpret_cast(packetBuffer))) { - HandlePacket(reinterpret_cast(packetBuffer)); + SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); + while(network.Receive(packetBuffer)) { + HandlePacket(packetBuffer); } + free(static_cast(packetBuffer)); } void LobbyMenu::FrameEnd() { @@ -204,10 +205,10 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) { void LobbyMenu::HandlePacket(SerialPacket* const argPacket) { switch(argPacket->type) { case SerialPacketType::BROADCAST_RESPONSE: - HandleBroadcastResponse(dynamic_cast(argPacket)); + HandleBroadcastResponse(static_cast(argPacket)); break; case SerialPacketType::JOIN_RESPONSE: - HandleJoinResponse(dynamic_cast(argPacket)); + HandleJoinResponse(static_cast(argPacket)); break; //handle errors default: diff --git a/common/network/packet/serial_packet_type.hpp b/common/network/packet/serial_packet_type.hpp index dceffaa..9142dcc 100644 --- a/common/network/packet/serial_packet_type.hpp +++ b/common/network/packet/serial_packet_type.hpp @@ -32,77 +32,77 @@ enum class SerialPacketType { //keep alive //ping => pong - PING, - PONG, + PING = 1, + PONG = 2, //search for the server list //none => server name, player count, version info (and source address) - BROADCAST_REQUEST, - BROADCAST_RESPONSE, + BROADCAST_REQUEST = 3, + BROADCAST_RESPONSE = 4, //try to join the server //username, and password => client index, account index - JOIN_REQUEST, - JOIN_RESPONSE, - JOIN_REJECTION, + JOIN_REQUEST = 5, + JOIN_RESPONSE = 6, + JOIN_REJECTION = 7, //mass update of all surrounding content //character.x, character.y => packet barrage - SYNCHRONIZE, + SYNCHRONIZE = 8, //disconnect from the server //autentication, account index => disconnect that account - DISCONNECT, + DISCONNECT = 9, //shut down the server //autentication => disconnect, shutdown - SHUTDOWN, + SHUTDOWN = 10, //map data //room index, region.x, region.y => room index, region.x, region.y, region content - REGION_REQUEST, - REGION_CONTENT, + REGION_REQUEST = 11, + REGION_CONTENT = 12, //combat data //TODO: system incomplete - COMBAT_NEW, - COMBAT_DELETE, - COMBAT_UPDATE, + COMBAT_NEW = 13, + COMBAT_DELETE = 14, + COMBAT_UPDATE = 15, - COMBAT_ENTER_REQUEST, - COMBAT_ENTER_RESPONSE, + COMBAT_ENTER_REQUEST = 16, + COMBAT_ENTER_RESPONSE = 17, - COMBAT_EXIT_REQUEST, - COMBAT_EXIT_RESPONSE, + COMBAT_EXIT_REQUEST = 18, + COMBAT_EXIT_RESPONSE = 19, //TODO: COMBAT info - COMBAT_REJECTION, + COMBAT_REJECTION = 20, //character data //character data => etc. - CHARACTER_NEW, - CHARACTER_DELETE, - CHARACTER_UPDATE, + CHARACTER_NEW = 21, + CHARACTER_DELETE = 22, + CHARACTER_UPDATE = 23, //authentication, character index => character stats - CHARACTER_STATS_REQUEST, - CHARACTER_STATS_RESPONSE, + CHARACTER_STATS_REQUEST= 24, + CHARACTER_STATS_RESPONSE = 25, //character new => character rejection, disconnect? - CHARACTER_REJECTION, + CHARACTER_REJECTION = 26, //enemy data //enemy data => etc. - ENEMY_NEW, - ENEMY_DELETE, - ENEMY_UPDATE, + ENEMY_NEW = 27, + ENEMY_DELETE = 28, + ENEMY_UPDATE = 29, - ENEMY_STATS_REQUEST, - ENEMY_STATS_RESPONSE, + ENEMY_STATS_REQUEST = 30, + ENEMY_STATS_RESPONSE = 31, //enemy index => enemy doens't exist - ENEMY_REJECTION, + ENEMY_REJECTION= 32, //NOTE: more packet types go here diff --git a/common/network/serial/serial.cpp b/common/network/serial/serial.cpp index 423f6c1..1e76e4b 100644 --- a/common/network/serial/serial.cpp +++ b/common/network/serial/serial.cpp @@ -56,7 +56,7 @@ void serializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_STATS_REQUEST: case SerialPacketType::CHARACTER_STATS_RESPONSE: - serializeCharacter(dynamic_cast(packet), buffer); + serializeCharacter(static_cast(packet), buffer); break; //client info @@ -65,7 +65,7 @@ void serializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::SYNCHRONIZE: case SerialPacketType::DISCONNECT: case SerialPacketType::SHUTDOWN: - serializeClient(dynamic_cast(packet), buffer); + serializeClient(static_cast(packet), buffer); break; //combat info @@ -79,7 +79,7 @@ void serializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::COMBAT_EXIT_REQUEST: case SerialPacketType::COMBAT_EXIT_RESPONSE: - serializeCombat(dynamic_cast(packet), buffer); + serializeCombat(static_cast(packet), buffer); break; //enemy info @@ -88,21 +88,21 @@ void serializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::ENEMY_UPDATE: case SerialPacketType::ENEMY_STATS_REQUEST: case SerialPacketType::ENEMY_STATS_RESPONSE: - serializeEnemy(dynamic_cast(packet), buffer); + serializeEnemy(static_cast(packet), buffer); break; //region info case SerialPacketType::REGION_REQUEST: - serializeRegionFormat(dynamic_cast(packet), buffer); + serializeRegionFormat(static_cast(packet), buffer); break; case SerialPacketType::REGION_CONTENT: - serializeRegionContent(dynamic_cast(packet), buffer); + serializeRegionContent(static_cast(packet), buffer); break; //server info case SerialPacketType::BROADCAST_RESPONSE: - serializeServer(dynamic_cast(packet), buffer); + serializeServer(static_cast(packet), buffer); break; } } @@ -132,7 +132,7 @@ void deserializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_STATS_REQUEST: case SerialPacketType::CHARACTER_STATS_RESPONSE: - deserializeCharacter(dynamic_cast(packet), buffer); + deserializeCharacter(static_cast(packet), buffer); break; //client info @@ -141,7 +141,7 @@ void deserializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::SYNCHRONIZE: case SerialPacketType::DISCONNECT: case SerialPacketType::SHUTDOWN: - deserializeClient(dynamic_cast(packet), buffer); + deserializeClient(static_cast(packet), buffer); break; //combat info @@ -155,7 +155,7 @@ void deserializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::COMBAT_EXIT_REQUEST: case SerialPacketType::COMBAT_EXIT_RESPONSE: - serializeCombat(dynamic_cast(packet), buffer); + serializeCombat(static_cast(packet), buffer); break; //enemy info @@ -164,21 +164,21 @@ void deserializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::ENEMY_UPDATE: case SerialPacketType::ENEMY_STATS_REQUEST: case SerialPacketType::ENEMY_STATS_RESPONSE: - serializeEnemy(dynamic_cast(packet), buffer); + serializeEnemy(static_cast(packet), buffer); break; //region info case SerialPacketType::REGION_REQUEST: - deserializeRegionFormat(dynamic_cast(packet), buffer); + deserializeRegionFormat(static_cast(packet), buffer); break; case SerialPacketType::REGION_CONTENT: - deserializeRegionContent(dynamic_cast(packet), buffer); + deserializeRegionContent(static_cast(packet), buffer); break; //server info case SerialPacketType::BROADCAST_RESPONSE: - deserializeServer(dynamic_cast(packet), buffer); + deserializeServer(static_cast(packet), buffer); break; } } \ No newline at end of file diff --git a/makefile b/makefile index 27fd80e..aaf0418 100644 --- a/makefile +++ b/makefile @@ -3,8 +3,7 @@ #MKDIR=mkdir #RM=del /y -CXXFLAGS+=-static-libgcc -static-libstdc++ -CFLAGS+=-static-libgcc +CXXFLAGS+=-static-libgcc -static-libstdc++ -g export diff --git a/server/server_application.cpp b/server/server_application.cpp index 6fd85d9..372655f 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -134,17 +134,18 @@ void ServerApplication::Init(int argc, char** argv) { } void ServerApplication::Proc() { - char packetBuffer[MAX_PACKET_SIZE]; + SerialPacket* packetBuffer = static_cast(malloc(MAX_PACKET_SIZE)); while(running) { //suck in the waiting packets & process them - while(network.Receive(reinterpret_cast(packetBuffer))) { - HandlePacket(reinterpret_cast(packetBuffer)); + while(network.Receive(packetBuffer)) { + HandlePacket(packetBuffer); } //update the internals //TODO: update the internals i.e. player positions //give the computer a break SDL_Delay(10); } + free(static_cast(packetBuffer)); } void ServerApplication::Quit() { @@ -168,21 +169,21 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { switch(argPacket->type) { //basic connections case SerialPacketType::BROADCAST_REQUEST: - HandleBroadcastRequest(dynamic_cast(argPacket)); + HandleBroadcastRequest(static_cast(argPacket)); break; case SerialPacketType::JOIN_REQUEST: - HandleJoinRequest(dynamic_cast(argPacket)); + HandleJoinRequest(static_cast(argPacket)); break; case SerialPacketType::DISCONNECT: - HandleDisconnect(dynamic_cast(argPacket)); + HandleDisconnect(static_cast(argPacket)); break; case SerialPacketType::SHUTDOWN: - HandleShutdown(dynamic_cast(argPacket)); + HandleShutdown(static_cast(argPacket)); break; //map management case SerialPacketType::REGION_REQUEST: - HandleRegionRequest(dynamic_cast(argPacket)); + HandleRegionRequest(static_cast(argPacket)); break; //combat management @@ -190,14 +191,14 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { //character management case SerialPacketType::CHARACTER_NEW: - HandleCharacterNew(dynamic_cast(argPacket)); + HandleCharacterNew(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(dynamic_cast(argPacket)); + HandleCharacterDelete(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_STATS_REQUEST: - HandleCharacterUpdate(dynamic_cast(argPacket)); + HandleCharacterUpdate(static_cast(argPacket)); break; //enemy management @@ -205,12 +206,12 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { //mismanagement case SerialPacketType::SYNCHRONIZE: - HandleSynchronize(dynamic_cast(argPacket)); + HandleSynchronize(static_cast(argPacket)); break; //handle errors default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(int(argPacket->type)))); + throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(static_cast(argPacket->type)) )); break; } } @@ -228,7 +229,7 @@ void ServerApplication::HandleBroadcastRequest(SerialPacket* const argPacket) { newPacket.playerCount = characterMgr.GetContainer()->size(); newPacket.version = NETWORK_VERSION; - network.SendTo(&argPacket->srcAddress, dynamic_cast(&newPacket)); + network.SendTo(&argPacket->srcAddress, static_cast(&newPacket)); } void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { @@ -251,7 +252,7 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { newPacket.clientIndex = clientUID; newPacket.accountIndex = accountIndex; - network.SendTo(&newClient.address, dynamic_cast(&newPacket)); + network.SendTo(&newClient.address, static_cast(&newPacket)); //finished this routine clientMap[clientUID++] = newClient; @@ -264,7 +265,7 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { //forward to the specified client network.SendTo( &clientMap[ accountMgr.GetAccount(argPacket->accountIndex)->clientIndex ].address, - dynamic_cast(argPacket) + static_cast(argPacket) ); //save and unload this account's characters @@ -315,7 +316,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->pager.GetRegion(argPacket->x, argPacket->y); //send the content - network.SendTo(&argPacket->srcAddress, dynamic_cast(argPacket)); + network.SendTo(&argPacket->srcAddress, static_cast(argPacket)); } //------------------------- @@ -435,7 +436,7 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) { for (auto& it : *characterMgr.GetContainer()) { newPacket.characterIndex = it.first; CopyCharacterToPacket(&newPacket, it.first); - network.SendTo(&client.address, dynamic_cast(&newPacket)); + network.SendTo(&client.address, static_cast(&newPacket)); } //TODO: more in HandleSynchronize() @@ -458,7 +459,7 @@ void ServerApplication::PumpCharacterUnload(int uid) { CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_DELETE; newPacket.characterIndex = uid; - PumpPacket(dynamic_cast(&newPacket)); + PumpPacket(static_cast(&newPacket)); } void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { From e57b04734340c2cffab7d1bc22b23da835870840 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Jun 2014 00:44:13 +1000 Subject: [PATCH 29/34] Added some basic code to RoomManager --- server/room_data.hpp | 10 +++---- server/room_manager.cpp | 52 +++++++++++++++++++++++------------ server/room_manager.hpp | 16 +++++++---- server/server_application.cpp | 2 +- todo.txt | 2 +- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/server/room_data.hpp b/server/room_data.hpp index 0787425..c37bbae 100644 --- a/server/room_data.hpp +++ b/server/room_data.hpp @@ -27,11 +27,11 @@ struct RoomData { enum class RoomType { - OVERWORLD, - RUINS, - TOWERS, - FORESTS, - CAVES, + OVERWORLD = 0, + RUINS = 1, + TOWERS = 2, + FORESTS = 3, + CAVE = 4, }; //members diff --git a/server/room_manager.cpp b/server/room_manager.cpp index 3cb43dd..8f60ba4 100644 --- a/server/room_manager.cpp +++ b/server/room_manager.cpp @@ -21,34 +21,52 @@ */ #include "room_manager.hpp" +#include + //------------------------- //public access methods //------------------------- -//TODO +RoomData* RoomManager::CreateRoom(int uid) { + //don't overwrite existing rooms + std::map::iterator it = roomMap.find(uid); + if (it != roomMap.end()) { + throw(std::runtime_error("Cannot overwrite an existing room")); + } + roomMap[uid] = new RoomData(); + //TODO: create room in the API + if (luaState) { + roomMap[uid]->pager.SetLuaState(luaState); + } + return roomMap[uid]; +} -//------------------------- -//accessors and mutators -//------------------------- +RoomData* RoomManager::UnloadRoom(int uid) { + //TODO: unload room in the API + delete roomMap[uid]; + roomMap.erase(uid); +} RoomData* RoomManager::GetRoom(int uid) { - std::map::iterator it = roomMap.find(uid); + RoomData* ptr = FindRoom(uid); + if (ptr) return ptr; + ptr = CreateRoom(uid); + return ptr; +} +RoomData* RoomManager::FindRoom(int uid) { + std::map::iterator it = roomMap.find(uid); if (it == roomMap.end()) { return nullptr; } - - return &it->second; + return it->second; } -std::map* RoomManager::GetContainer() { - return &roomMap; -} - -lua_State* RoomManager::SetLuaState(lua_State* L) { - return luaState = L; -} - -lua_State* RoomManager::GetLuaState() { - return luaState; +RoomData* RoomManager::PushRoom(int uid, RoomData* room) { + //unload existing rooms with this index + std::map::iterator it = roomMap.find(uid); + if (it != roomMap.end()) { + UnloadRoom(uid); + } + roomMap[uid] = room; } diff --git a/server/room_manager.hpp b/server/room_manager.hpp index 655c960..80480f7 100644 --- a/server/room_manager.hpp +++ b/server/room_manager.hpp @@ -36,17 +36,21 @@ public: ~RoomManager() = default; //public access methods - //TODO: Fill this out + RoomData* CreateRoom(int uid); + RoomData* UnloadRoom(int uid); + + RoomData* GetRoom(int uid); + RoomData* FindRoom(int uid); + RoomData* PushRoom(int uid, RoomData*); //accessors and mutators - RoomData* GetRoom(int uid); - std::map* GetContainer(); + std::map* GetContainer() { return &roomMap; } - lua_State* SetLuaState(lua_State*); - lua_State* GetLuaState(); + lua_State* SetLuaState(lua_State* L) { return luaState = L; } + lua_State* GetLuaState() { return luaState; } private: - std::map roomMap; + std::map roomMap; lua_State* luaState = nullptr; }; diff --git a/server/server_application.cpp b/server/server_application.cpp index 372655f..621f129 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -316,7 +316,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->pager.GetRegion(argPacket->x, argPacket->y); //send the content - network.SendTo(&argPacket->srcAddress, static_cast(argPacket)); + network.SendTo(&argPacket->srcAddress, static_cast(&newPacket)); } //------------------------- diff --git a/todo.txt b/todo.txt index 20fbe42..4feb30b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,5 @@ +TODO: encapsulate the data structures TODO: Get the rooms working -TODO: update the map API to handle multiple rooms TODO: Rejection packets TODO: Authentication From 793737e1eddbdf75deea50f05373e4e26d64b03e Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Jun 2014 03:05:21 +1000 Subject: [PATCH 30/34] Experimenting with the map --- common/map/pager_api.cpp | 20 +- common/map/region.cpp | 19 +- common/map/region.hpp | 1 + common/map/region_pager.cpp | 205 ------------------ common/map/region_pager_base.cpp | 82 +++++++ common/map/region_pager_base.hpp | 55 +++++ common/map/region_pager_lua.cpp | 126 +++++++++++ ...{region_pager.hpp => region_pager_lua.hpp} | 37 +--- 8 files changed, 299 insertions(+), 246 deletions(-) delete mode 100644 common/map/region_pager.cpp create mode 100644 common/map/region_pager_base.cpp create mode 100644 common/map/region_pager_base.hpp create mode 100644 common/map/region_pager_lua.cpp rename common/map/{region_pager.hpp => region_pager_lua.hpp} (63%) diff --git a/common/map/pager_api.cpp b/common/map/pager_api.cpp index 332cc5e..8f60e61 100644 --- a/common/map/pager_api.cpp +++ b/common/map/pager_api.cpp @@ -21,42 +21,42 @@ */ #include "pager_api.hpp" -#include "region_pager.hpp" +#include "region_pager_lua.hpp" #include "region.hpp" #include #include static int setTile(lua_State* L) { - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); int ret = pager->SetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); lua_pushinteger(L, ret); return 1; } static int getTile(lua_State* L) { - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); int ret = pager->GetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); lua_pushinteger(L, ret); return 1; } static int getRegion(lua_State* L) { - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); lua_pushlightuserdata(L, region); return 1; } static int setDirectory(lua_State* L) { - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); std::string s = pager->SetDirectory(lua_tostring(L, 2)); lua_pushstring(L, s.c_str()); return 1; } static int getDirectory(lua_State* L) { - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); std::string s = pager->GetDirectory(); lua_pushstring(L, s.c_str()); return 1; @@ -64,7 +64,7 @@ static int getDirectory(lua_State* L) { static int loadRegion(lua_State* L) { //get the parameters - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); std::string s = pager->GetDirectory(); @@ -83,7 +83,7 @@ static int loadRegion(lua_State* L) { static int saveRegion(lua_State* L) { //get the parameters - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); std::string s = pager->GetDirectory(); @@ -102,7 +102,7 @@ static int saveRegion(lua_State* L) { static int createRegion(lua_State* L) { //get the parameters - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); //push the parameters @@ -120,7 +120,7 @@ static int createRegion(lua_State* L) { static int unloadRegion(lua_State* L) { //get the parameters - RegionPager* pager = reinterpret_cast(lua_touserdata(L, 1)); + RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); std::string s = pager->GetDirectory(); diff --git a/common/map/region.cpp b/common/map/region.cpp index ffdbdf1..8de957b 100644 --- a/common/map/region.cpp +++ b/common/map/region.cpp @@ -21,13 +21,20 @@ */ #include "region.hpp" -Region::Region(int argX, int argY): - x(argX), - y(argY) -{ - for (register int i = 0; i < REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH; ++i) { - *(reinterpret_cast(tiles) + i) = 0; +#include "utility.hpp" + +#include +#include + +Region::Region(int argX, int argY): x(argX), y(argY) { + if (x != snapToBase(REGION_WIDTH, x) || y != snapToBase(REGION_HEIGHT, y)) { + throw(std::invalid_argument("Region location is off grid")); } + memset(tiles, 0, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t)); +} + +Region::Region(Region const& rhs): x(rhs.x), y(rhs.y) { + memcpy(tiles, rhs.tiles, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t)); } Region::type_t Region::SetTile(int x, int y, int z, type_t v) { diff --git a/common/map/region.hpp b/common/map/region.hpp index 4c0d2cd..74fc013 100644 --- a/common/map/region.hpp +++ b/common/map/region.hpp @@ -32,6 +32,7 @@ public: Region() = delete; Region(int x, int y); + Region(Region const&); ~Region() = default; type_t SetTile(int x, int y, int z, type_t v); diff --git a/common/map/region_pager.cpp b/common/map/region_pager.cpp deleted file mode 100644 index e9e9b1c..0000000 --- a/common/map/region_pager.cpp +++ /dev/null @@ -1,205 +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 "region_pager.hpp" - -#include "utility.hpp" - -#include - -Region::type_t RegionPager::SetTile(int x, int y, int z, Region::type_t v) { - Region* ptr = GetRegion(x, y); - return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v); -} - -Region::type_t RegionPager::GetTile(int x, int y, int z) { - Region* ptr = GetRegion(x, y); - return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z); -} - -Region* RegionPager::GetRegion(int x, int y) { - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //get the region by various means - Region* ptr = nullptr; - ptr = FindRegion(x, y); - if (ptr) return ptr; - ptr = LoadRegion(x, y); - if (ptr) return ptr; - return CreateRegion(x, y); -} - -Region* RegionPager::FindRegion(int x, int y) { - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //find the region - for (std::list::iterator it = regionList.begin(); it != regionList.end(); it++) { - if ((*it)->GetX() == x && (*it)->GetY() == y) { - return *it; - } - } - return nullptr; -} - -Region* RegionPager::PushRegion(Region* const region) { - if ( - region->GetX() != snapToBase(REGION_WIDTH, region->GetX()) || - region->GetY() != snapToBase(REGION_HEIGHT, region->GetY()) - ) - { - throw(std::runtime_error("Pushed region does not conform to the region grid")); - } - - regionList.push_front(region); - return regionList.front(); -} - -Region* RegionPager::LoadRegion(int x, int y) { - //only work if using lua - if (!luaState) { - throw(std::runtime_error("RegionPager::luaState is null")); - } - - //load the region if possible - - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //overwrite? - Region* ptr = FindRegion(x, y); - if (!ptr) { - ptr = new Region(x, y); - } - - //API hook - lua_getglobal(luaState, "region"); - lua_getfield(luaState, -1, "load"); - lua_pushlightuserdata(luaState, ptr); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); - } - if (lua_toboolean(luaState, -1)) { - regionList.push_front(ptr); - } - else { - delete ptr; - ptr = nullptr; - } - lua_pop(luaState, 2); - - return ptr; -} - -Region* RegionPager::SaveRegion(int x, int y) { - //only work if using lua - if (!luaState) { - throw(std::runtime_error("RegionPager::luaState is null")); - } - - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //find & save the region - Region* ptr = FindRegion(x, y); - if (ptr) { - //API hook - lua_getglobal(luaState, "region"); - lua_getfield(luaState, -1, "save"); - lua_pushlightuserdata(luaState, ptr); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); - } - lua_pop(luaState, 1); - } - return ptr; -} - -Region* RegionPager::CreateRegion(int x, int y) { - //only work if using lua - if (!luaState) { - throw(std::runtime_error("RegionPager::luaState is null")); - } - - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - //overwrite? - Region* ptr = FindRegion(x, y); - if (!ptr) { - ptr = new Region(x, y); - } - - //API hook - lua_getglobal(luaState, "region"); - lua_getfield(luaState, -1, "create"); - lua_pushlightuserdata(luaState, ptr); - //TODO: parameters - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); - } - lua_pop(luaState, 1); - - regionList.push_front(ptr); - return ptr; -} - -void RegionPager::UnloadRegion(int x, int y) { - //only work if using lua - if (!luaState) { - throw(std::runtime_error("RegionPager::luaState is null")); - } - - //snap the coords - x = snapToBase(REGION_WIDTH, x); - y = snapToBase(REGION_HEIGHT, y); - - lua_getglobal(luaState, "region"); - - //custom loop, not FindRegion() - for (std::list::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) { - if ((*it)->GetX() == x && (*it)->GetY() == y) { - - //API hook - lua_getfield(luaState, -1, "unload"); - lua_pushlightuserdata(luaState, *it); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); - } - - delete (*it); - it = regionList.erase(it); - continue; - } - ++it; - } - - lua_pop(luaState, 1); -} diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp new file mode 100644 index 0000000..a403c65 --- /dev/null +++ b/common/map/region_pager_base.cpp @@ -0,0 +1,82 @@ +/* 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 "region_pager_base.hpp" + +#include "utility.hpp" + +#include +#include + +Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) { + Region* ptr = GetRegion(x, y); + return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v); +} + +Region::type_t RegionPagerBase::GetTile(int x, int y, int z) { + Region* ptr = GetRegion(x, y); + return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z); +} + +Region* RegionPagerBase::GetRegion(int x, int y) { + //get the region by various means + Region* ptr = nullptr; + ptr = FindRegion(x, y); + if (ptr) return ptr; + ptr = LoadRegion(x, y); + if (ptr) return ptr; + return CreateRegion(x, y); +} + +Region* RegionPagerBase::FindRegion(int x, int y) { + //find the region + std::list::iterator it = find_if(regionList.begin(), regionList.end(), [x, y](Region& region) -> bool { + return region.GetX() == x && region.GetY() == y; + }); + return it != regionList.end() ? &(*it) : nullptr; +} + +Region* RegionPagerBase::LoadRegion(int x, int y) { + //TODO: load the region if possible + return nullptr; +} + +Region* RegionPagerBase::SaveRegion(int x, int y) { + //TODO: find & save the region + return nullptr; +} + +Region* RegionPagerBase::CreateRegion(int x, int y) { + if (FindRegion(x, y)) { + throw(std::logic_error("Cannot overwrite an existing region")); + } + regionList.emplace_front(x, y); + return ®ionList.front(); +} + +void RegionPagerBase::UnloadRegion(int x, int y) { + //custom loop, not FindRegion() + regionList.remove_if([x, y](Region& region) -> bool { return region.GetX() == x && region.GetY() == y; }); +} + +void RegionPagerBase::UnloadAll() { + regionList.clear(); +} \ No newline at end of file diff --git a/common/map/region_pager_base.hpp b/common/map/region_pager_base.hpp new file mode 100644 index 0000000..3f7881c --- /dev/null +++ b/common/map/region_pager_base.hpp @@ -0,0 +1,55 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef REGIONPAGERBASE_HPP_ +#define REGIONPAGERBASE_HPP_ + +#include "region.hpp" + +#include + +class RegionPagerBase { +public: + RegionPagerBase() = default; + virtual ~RegionPagerBase() { UnloadAll(); }; + + //tile manipulation + virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v); + virtual Region::type_t GetTile(int x, int y, int z); + + //region manipulation + virtual Region* GetRegion(int x, int y); + virtual Region* FindRegion(int x, int y); + + virtual Region* LoadRegion(int x, int y); + virtual Region* SaveRegion(int x, int y); + virtual Region* CreateRegion(int x, int y); + virtual void UnloadRegion(int x, int y); + + virtual void UnloadAll(); + + //accessors & mutators + std::list* GetContainer() { return ®ionList; } +protected: + std::list regionList; +}; + +#endif diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp new file mode 100644 index 0000000..a183be8 --- /dev/null +++ b/common/map/region_pager_lua.cpp @@ -0,0 +1,126 @@ +/* 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 "region_pager_lua.hpp" + +#include "utility.hpp" + +#include + +Region* RegionPagerLua::LoadRegion(int x, int y) { + //load the region if possible + + //something to work on + regionList.emplace_front(x, y); + + //API hook + lua_getglobal(luaState, "region"); + lua_getfield(luaState, -1, "load"); + lua_pushlightuserdata(luaState, ®ionList.front()); + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + //success or failure + if (!lua_toboolean(luaState, -1)) { + lua_pop(luaState, 2); + regionList.pop_front(); + return nullptr; + } + lua_pop(luaState, 2); + 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(luaState, "region"); + lua_getfield(luaState, -1, "save"); + lua_pushlightuserdata(luaState, ptr); + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + lua_pop(luaState, 1); + } + return ptr; +} + +Region* RegionPagerLua::CreateRegion(int x, int y) { + if (FindRegion(x, y)) { + throw(std::logic_error("Cannot overwrite an existing region")); + } + + //something to work on + regionList.emplace_front(x, y); + + //API hook + lua_getglobal(luaState, "region"); + lua_getfield(luaState, -1, "create"); + lua_pushlightuserdata(luaState, ®ionList.front()); + //TODO: parameters + if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + lua_pop(luaState, 1); + return ®ionList.front();; +} + +void RegionPagerLua::UnloadRegion(int x, int y) { + lua_getglobal(luaState, "region"); + + regionList.remove_if([&](Region& region) -> bool { + if (region.GetX() == x && region.GetY() == y) { + + //API hook + lua_getfield(luaState, -1, "unload"); + lua_pushlightuserdata(luaState, ®ion); + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + + return true; + } + return false; + }); + + lua_pop(luaState, 1); +} + +void RegionPagerLua::UnloadAll() { + lua_getglobal(luaState, "region"); + + for (auto& it : regionList) { + //API hook + lua_getfield(luaState, -1, "unload"); + lua_pushlightuserdata(luaState, &it); + lua_pushstring(luaState, directory.c_str()); + if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + } + } + + lua_pop(luaState, 1); + regionList.clear(); +} \ No newline at end of file diff --git a/common/map/region_pager.hpp b/common/map/region_pager_lua.hpp similarity index 63% rename from common/map/region_pager.hpp rename to common/map/region_pager_lua.hpp index 06ead7c..78aed17 100644 --- a/common/map/region_pager.hpp +++ b/common/map/region_pager_lua.hpp @@ -19,47 +19,34 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef REGIONPAGER_HPP_ -#define REGIONPAGER_HPP_ +#ifndef REGIONPAGERLUA_HPP_ +#define REGIONPAGERLUA_HPP_ -#include "region.hpp" +#include "region_pager_base.hpp" #include "lua/lua.hpp" -#include #include -//TODO: split this into two: "RegionPagerBase" and "RegionPagerLua" -class RegionPager { +class RegionPagerLua : public RegionPagerBase { public: - RegionPager() = default; - ~RegionPager() = default; - - //tile manipulation - Region::type_t SetTile(int x, int y, int z, Region::type_t v); - Region::type_t GetTile(int x, int y, int z); + RegionPagerLua() = default; + ~RegionPagerLua() = default; //region manipulation - Region* GetRegion(int x, int y); - Region* FindRegion(int x, int y); - Region* PushRegion(Region* const); + Region* LoadRegion(int x, int y) override; + Region* SaveRegion(int x, int y) override; + Region* CreateRegion(int x, int y) override; + void UnloadRegion(int x, int y) override; - Region* LoadRegion(int x, int y); - Region* SaveRegion(int x, int y); - Region* CreateRegion(int x, int y); - void UnloadRegion(int x, int y); - - //accessors & mutators - std::list* GetContainer() { return ®ionList; } + void UnloadAll() override; std::string SetDirectory(std::string s) { return directory = s; } std::string GetDirectory() { return directory; } lua_State* SetLuaState(lua_State* L) { return luaState = L; } lua_State* GetLuaState() { return luaState; } - -private: - std::list regionList; +protected: std::string directory; lua_State* luaState = nullptr; }; From b418ad713dd2c7113e8660e0c4e1f6caa5d61ded Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Jun 2014 03:38:13 +1000 Subject: [PATCH 31/34] Worked these changes into the client & server (read more) The changes were fairly easy, and I was actually able to find and fix an out-of-sequence bug: The destructors for the AccountManager and the CharacterManager were using SQL code after the call to SQLite3_close_v2(), so I added and called UnloadAll() for both of them. --- client/in_world.cpp | 17 ++++++++++------- client/in_world.hpp | 4 ++-- common/map/region_pager_base.cpp | 5 +++++ common/map/region_pager_base.hpp | 1 + server/account_manager.cpp | 19 ++++++++----------- server/account_manager.hpp | 6 ++++-- server/character_manager.cpp | 17 +++++++---------- server/character_manager.hpp | 6 ++++-- server/room_data.hpp | 4 ++-- server/server_application.cpp | 8 ++++++++ 10 files changed, 51 insertions(+), 36 deletions(-) diff --git a/client/in_world.cpp b/client/in_world.cpp index 9779a71..3acad2f 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -128,9 +128,9 @@ void InWorld::RenderFrame() { } void InWorld::Render(SDL_Surface* const screen) { - //draw the map - for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { - tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y); + //draw the map0 + for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { + tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y); } //draw characters @@ -343,6 +343,9 @@ void InWorld::HandleRegionContent(RegionPacket* const argPacket) { //replace existing regions regionPager.UnloadRegion(argPacket->x, argPacket->y); regionPager.PushRegion(argPacket->region); + + //clean up after the serial code + delete argPacket->region; argPacket->region = nullptr; } @@ -431,13 +434,13 @@ void InWorld::UpdateMap() { int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT; //prune distant regions - for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) { + for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) { //check if the region is outside off this area - if ((*it)->GetX() < xStart || (*it)->GetX() > xEnd || (*it)->GetY() < yStart || (*it)->GetY() > yEnd) { + if (it->GetX() < xStart || it->GetX() > xEnd || it->GetY() < yStart || it->GetY() > yEnd) { //clunky, but the alternative was time consuming - int tmpX = (*it)->GetX(); - int tmpY = (*it)->GetY(); + int tmpX = it->GetX(); + int tmpY = it->GetY(); ++it; regionPager.UnloadRegion(tmpX, tmpY); diff --git a/client/in_world.hpp b/client/in_world.hpp index 526c72a..156d35e 100644 --- a/client/in_world.hpp +++ b/client/in_world.hpp @@ -23,7 +23,7 @@ #define INWORLD_HPP_ //maps -#include "region_pager.hpp" +#include "region_pager_base.hpp" //networking #include "udp_network_utility.hpp" @@ -110,7 +110,7 @@ protected: TileSheet tileSheet; //map - RegionPager regionPager; + RegionPagerBase regionPager; //UI Button disconnectButton; diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp index a403c65..a8ad76f 100644 --- a/common/map/region_pager_base.cpp +++ b/common/map/region_pager_base.cpp @@ -54,6 +54,11 @@ Region* RegionPagerBase::FindRegion(int x, int y) { return it != regionList.end() ? &(*it) : nullptr; } +Region* RegionPagerBase::PushRegion(Region* const ptr) { + regionList.push_front(*ptr); + return ®ionList.front(); +} + Region* RegionPagerBase::LoadRegion(int x, int y) { //TODO: load the region if possible return nullptr; diff --git a/common/map/region_pager_base.hpp b/common/map/region_pager_base.hpp index 3f7881c..004faa4 100644 --- a/common/map/region_pager_base.hpp +++ b/common/map/region_pager_base.hpp @@ -38,6 +38,7 @@ public: //region manipulation virtual Region* GetRegion(int x, int y); virtual Region* FindRegion(int x, int y); + virtual Region* PushRegion(Region* const); virtual Region* LoadRegion(int x, int y); virtual Region* SaveRegion(int x, int y); diff --git a/server/account_manager.cpp b/server/account_manager.cpp index 2a5a968..c29bd29 100644 --- a/server/account_manager.cpp +++ b/server/account_manager.cpp @@ -36,16 +36,6 @@ static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;"; //Define the public methods //------------------------- -AccountManager::AccountManager() { - // -} - -AccountManager::~AccountManager() { - for (auto& it : accountMap) { - SaveAccount(it.first); - } -} - int AccountManager::CreateAccount(std::string username, int clientIndex) { //create this user account, failing if it exists, leave this account in memory sqlite3_stmt* statement = nullptr; @@ -202,6 +192,13 @@ void AccountManager::DeleteAccount(int uid) { accountMap.erase(uid); } +void AccountManager::UnloadAll() { + for (auto& it : accountMap) { + SaveAccount(it.first); + } + accountMap.clear(); +} + //------------------------- //Define the accessors and mutators //------------------------- @@ -226,4 +223,4 @@ sqlite3* AccountManager::SetDatabase(sqlite3* db) { sqlite3* AccountManager::GetDatabase() { return database; -} \ No newline at end of file +} diff --git a/server/account_manager.hpp b/server/account_manager.hpp index 5bf3841..7c6cc1f 100644 --- a/server/account_manager.hpp +++ b/server/account_manager.hpp @@ -30,8 +30,8 @@ class AccountManager { public: - AccountManager(); - ~AccountManager(); + AccountManager() = default; + ~AccountManager() { UnloadAll(); }; //public access methods int CreateAccount(std::string username, int clientIndex); @@ -40,6 +40,8 @@ public: void UnloadAccount(int uid); void DeleteAccount(int uid); + void UnloadAll(); + //accessors and mutators AccountData* GetAccount(int uid); std::map* GetContainer(); diff --git a/server/character_manager.cpp b/server/character_manager.cpp index 0a1d4d7..21eb99a 100644 --- a/server/character_manager.cpp +++ b/server/character_manager.cpp @@ -58,16 +58,6 @@ static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; //Define the methods //------------------------- -CharacterManager::CharacterManager() { - // -} - -CharacterManager::~CharacterManager() { - for (auto& it : characterMap) { - SaveCharacter(it.first); - } -} - //TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) { //Create the character, failing if it exists @@ -294,6 +284,13 @@ void CharacterManager::UnloadCharacterIf(std::function::iterator)> f); + void UnloadAll(); + //accessors and mutators CharacterData* GetCharacter(int uid); std::map* GetContainer(); diff --git a/server/room_data.hpp b/server/room_data.hpp index c37bbae..cf1b6cb 100644 --- a/server/room_data.hpp +++ b/server/room_data.hpp @@ -23,7 +23,7 @@ #define ROOMDATA_HPP_ //map system -#include "region_pager.hpp" +#include "region_pager_lua.hpp" struct RoomData { enum class RoomType { @@ -35,7 +35,7 @@ struct RoomData { }; //members - RegionPager pager; + RegionPagerLua pager; RoomType type; //TODO: collision map diff --git a/server/server_application.cpp b/server/server_application.cpp index 621f129..12c740f 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -151,6 +151,14 @@ void ServerApplication::Proc() { void ServerApplication::Quit() { std::cout << "Shutting down" << std::endl; + //close the managers + clientMap.clear(); + accountMgr.UnloadAll(); + characterMgr.UnloadAll(); + //TODO: unload combats + //TODO: unload enemies + //TODO: unload rooms + //APIs lua_close(luaState); sqlite3_close_v2(database); From c0210325125fd0298e00300e0ae5e258e3476c9b Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Jun 2014 22:37:21 +1000 Subject: [PATCH 32/34] The character is visible, fixed a database issue --- client/in_world.cpp | 1 - client/lobby_menu.cpp | 8 +++++++- client/main_menu.cpp | 10 ++++++++++ common/network/packet/serial_packet_base.hpp | 4 ++-- common/network/serial/serial_client.cpp | 8 ++++---- server/server_application.cpp | 17 +++++++++++++---- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/client/in_world.cpp b/client/in_world.cpp index 3acad2f..b5cc028 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -301,7 +301,6 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { localCharacter = &character; //setup the camera - //TODO: can't change the screen size? camera.width = GetScreen()->w; camera.height = GetScreen()->h; diff --git a/client/lobby_menu.cpp b/client/lobby_menu.cpp index facfa9f..8cbf55a 100644 --- a/client/lobby_menu.cpp +++ b/client/lobby_menu.cpp @@ -238,5 +238,11 @@ void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) { network.Bind(&argPacket->srcAddress, Channels::SERVER); SetNextScene(SceneList::INWORLD); - //TODO: send this player's character info + //send this player's character info + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_NEW; + strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE); + strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE); + newPacket.accountIndex = accountIndex; + network.SendTo(Channels::SERVER, &newPacket); } \ No newline at end of file diff --git a/client/main_menu.cpp b/client/main_menu.cpp index b5d633e..c33766c 100644 --- a/client/main_menu.cpp +++ b/client/main_menu.cpp @@ -21,6 +21,11 @@ */ #include "main_menu.hpp" +#include + +using std::cout; +using std::endl; + //------------------------- //Public access members //------------------------- @@ -53,6 +58,11 @@ MainMenu::MainMenu(ConfigUtility* const argConfig): startButton.SetText("Start"); optionsButton.SetText("Options"); quitButton.SetText("Quit"); + + //debug + cout << config["client.username"] << endl; + cout << config["client.handle"] << endl; + cout << config["client.avatar"] << endl; } MainMenu::~MainMenu() { diff --git a/common/network/packet/serial_packet_base.hpp b/common/network/packet/serial_packet_base.hpp index b84816e..156d1e5 100644 --- a/common/network/packet/serial_packet_base.hpp +++ b/common/network/packet/serial_packet_base.hpp @@ -30,8 +30,8 @@ #include "SDL/SDL_net.h" -#define NETWORK_VERSION 20140607 -#define PACKET_STRING_SIZE 100 +constexpr int NETWORK_VERSION = 20140607; +constexpr int PACKET_STRING_SIZE = 100; struct SerialPacketBase { //members diff --git a/common/network/serial/serial_client.cpp b/common/network/serial/serial_client.cpp index c96449d..96bc881 100644 --- a/common/network/serial/serial_client.cpp +++ b/common/network/serial/serial_client.cpp @@ -28,8 +28,8 @@ void serializeClient(ClientPacket* packet, void* buffer) { SERIALIZE(buffer, &packet->clientIndex, sizeof(int)); SERIALIZE(buffer, &packet->accountIndex, sizeof(int)); - SERIALIZE(buffer, &packet->username, sizeof(PACKET_STRING_SIZE)); -// SERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); + SERIALIZE(buffer, &packet->username, PACKET_STRING_SIZE); +// SERIALIZE(buffer, &packet->password, PACKET_STRING_SIZE); } void deserializeClient(ClientPacket* packet, void* buffer) { @@ -37,6 +37,6 @@ void deserializeClient(ClientPacket* packet, void* buffer) { DESERIALIZE(buffer, &packet->clientIndex, sizeof(int)); DESERIALIZE(buffer, &packet->accountIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->username, sizeof(PACKET_STRING_SIZE)); -// DESERIALIZE(buffer, &packet->password, sizeof(PACKET_STRING_SIZE)); + DESERIALIZE(buffer, &packet->username, PACKET_STRING_SIZE); +// DESERIALIZE(buffer, &packet->password, PACKET_STRING_SIZE); } diff --git a/server/server_application.cpp b/server/server_application.cpp index 4c576f5..9aee4c8 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -29,6 +29,9 @@ #include #include +using std::cout; +using std::endl; + //------------------------- //public methods //------------------------- @@ -233,7 +236,7 @@ void ServerApplication::HandleBroadcastRequest(SerialPacket* const argPacket) { ServerPacket newPacket; newPacket.type = SerialPacketType::BROADCAST_RESPONSE; - snprintf(newPacket.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); + strncpy(newPacket.name, config["server.name"].c_str(), PACKET_STRING_SIZE); newPacket.playerCount = characterMgr.GetContainer()->size(); newPacket.version = NETWORK_VERSION; @@ -241,6 +244,8 @@ void ServerApplication::HandleBroadcastRequest(SerialPacket* const argPacket) { } void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { + cout << "Attempting connection: " << argPacket->username << endl; + //create the new client ClientData newClient; newClient.address = argPacket->srcAddress; @@ -268,6 +273,7 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { } void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { + cout << "Trying to disconnect account " << argPacket->accountIndex << endl; //TODO: authenticate who is disconnecting/kicking //forward to the specified client @@ -281,8 +287,10 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { characterMgr.UnloadCharacterIf([&](std::map::iterator it) -> bool { if (argPacket->accountIndex == it->second.owner) { PumpCharacterUnload(it->first); + cout << "Deleting character " << it->first << endl; return true; } + cout << "Not deleting character " << it->first << endl; return false; }); @@ -338,7 +346,8 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { //------------------------- void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) { - int characterIndex = characterMgr.CreateCharacter(argPacket->accountIndex, argPacket->handle, argPacket->avatar); + //NOTE: misnomer, try to load the character first + int characterIndex = characterMgr.LoadCharacter(argPacket->accountIndex, argPacket->handle, argPacket->avatar); if (characterIndex == -1) { //TODO: rejection packet @@ -478,8 +487,8 @@ void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int //TODO: keep this up to date when the character changes packet->characterIndex = characterIndex; - snprintf(packet->handle, PACKET_STRING_SIZE, "%s", character->handle.c_str()); - snprintf(packet->avatar, PACKET_STRING_SIZE, "%s", character->avatar.c_str()); + 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; From a23fbbfb381df6f68321eafc7d8eb3fc32327110 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Jun 2014 23:13:11 +1000 Subject: [PATCH 33/34] Characters are working correctly again --- client/in_world.cpp | 13 +++++++++++-- client/main_menu.cpp | 9 +-------- makefile | 2 +- server/server_application.cpp | 8 -------- todo.txt | 1 + 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/client/in_world.cpp b/client/in_world.cpp index b5cc028..76435c8 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -128,7 +128,7 @@ void InWorld::RenderFrame() { } void InWorld::Render(SDL_Surface* const screen) { - //draw the map0 + //draw the map for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y); } @@ -185,6 +185,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { case SDLK_LEFT: if (localCharacter) { localCharacter->motion.x -= CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -192,6 +193,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { case SDLK_RIGHT: if (localCharacter) { localCharacter->motion.x += CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -199,6 +201,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { case SDLK_UP: if (localCharacter) { localCharacter->motion.y -= CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -206,6 +209,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { case SDLK_DOWN: if (localCharacter) { localCharacter->motion.y += CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -218,6 +222,7 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { case SDLK_LEFT: if (localCharacter) { localCharacter->motion.x += CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -225,6 +230,7 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { case SDLK_RIGHT: if (localCharacter) { localCharacter->motion.x -= CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -232,6 +238,7 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { case SDLK_UP: if (localCharacter) { localCharacter->motion.y += CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -239,6 +246,7 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { case SDLK_DOWN: if (localCharacter) { localCharacter->motion.y -= CHARACTER_WALKING_SPEED; + localCharacter->CorrectSprite(); SendPlayerUpdate(); } break; @@ -297,7 +305,8 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { character.CorrectSprite(); //catch this client's player object - if (argPacket->characterIndex == characterIndex && !localCharacter) { + if (argPacket->accountIndex == accountIndex && !localCharacter) { + characterIndex = argPacket->characterIndex; localCharacter = &character; //setup the camera diff --git a/client/main_menu.cpp b/client/main_menu.cpp index c33766c..457bd12 100644 --- a/client/main_menu.cpp +++ b/client/main_menu.cpp @@ -21,11 +21,6 @@ */ #include "main_menu.hpp" -#include - -using std::cout; -using std::endl; - //------------------------- //Public access members //------------------------- @@ -60,9 +55,7 @@ MainMenu::MainMenu(ConfigUtility* const argConfig): quitButton.SetText("Quit"); //debug - cout << config["client.username"] << endl; - cout << config["client.handle"] << endl; - cout << config["client.avatar"] << endl; + // } MainMenu::~MainMenu() { diff --git a/makefile b/makefile index aaf0418..080a22d 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ #MKDIR=mkdir #RM=del /y -CXXFLAGS+=-static-libgcc -static-libstdc++ -g +CXXFLAGS+=-static-libgcc -static-libstdc++ export diff --git a/server/server_application.cpp b/server/server_application.cpp index 9aee4c8..4bc1644 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -29,9 +29,6 @@ #include #include -using std::cout; -using std::endl; - //------------------------- //public methods //------------------------- @@ -244,8 +241,6 @@ void ServerApplication::HandleBroadcastRequest(SerialPacket* const argPacket) { } void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { - cout << "Attempting connection: " << argPacket->username << endl; - //create the new client ClientData newClient; newClient.address = argPacket->srcAddress; @@ -273,7 +268,6 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { } void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { - cout << "Trying to disconnect account " << argPacket->accountIndex << endl; //TODO: authenticate who is disconnecting/kicking //forward to the specified client @@ -287,10 +281,8 @@ void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) { characterMgr.UnloadCharacterIf([&](std::map::iterator it) -> bool { if (argPacket->accountIndex == it->second.owner) { PumpCharacterUnload(it->first); - cout << "Deleting character " << it->first << endl; return true; } - cout << "Not deleting character " << it->first << endl; return false; }); diff --git a/todo.txt b/todo.txt index 4feb30b..d9279d1 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,4 @@ +TODO: rename restart scene to cleanup scene TODO: encapsulate the data structures TODO: Get the rooms working From bd5e57401e1a5321fb6c852a8b391e3662286015 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Jun 2014 23:27:33 +1000 Subject: [PATCH 34/34] Minor comment tweaks --- client/in_world.cpp | 2 +- common/gameplay/combat_data.hpp | 2 +- common/network/serial/serial.cpp | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/client/in_world.cpp b/client/in_world.cpp index 76435c8..abd311e 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -338,7 +338,7 @@ void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) { CharacterData& character = characterMap[argPacket->characterIndex]; - //TODO: review this + //other characters moving if (argPacket->characterIndex != characterIndex) { character.roomIndex = argPacket->roomIndex; character.origin = argPacket->origin; diff --git a/common/gameplay/combat_data.hpp b/common/gameplay/combat_data.hpp index 3c45b78..b170e5f 100644 --- a/common/gameplay/combat_data.hpp +++ b/common/gameplay/combat_data.hpp @@ -43,7 +43,7 @@ struct CombatData { enum class Terrain { - //TODO: types of terrains + //TODO: types of combat terrains NONE = 0, GRASSLANDS, }; diff --git a/common/network/serial/serial.cpp b/common/network/serial/serial.cpp index 1e76e4b..791da27 100644 --- a/common/network/serial/serial.cpp +++ b/common/network/serial/serial.cpp @@ -73,7 +73,6 @@ void serializePacket(SerialPacketBase* packet, void* buffer) { case SerialPacketType::COMBAT_DELETE: case SerialPacketType::COMBAT_UPDATE: - //TODO: is this the best fit? case SerialPacketType::COMBAT_ENTER_REQUEST: case SerialPacketType::COMBAT_ENTER_RESPONSE: case SerialPacketType::COMBAT_EXIT_REQUEST: