From de1cd8d6a8bcd36aa1385835b727bad0a519002a Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 13 Jan 2015 00:04:42 +1100 Subject: [PATCH 01/21] Began expanding network protocols for monsters All big feature expansions have begun with SerialPacketType, and this is no exception. --- common/network/serial_packet.hpp | 2 +- common/network/serial_packet_type.hpp | 89 ++++++++++++++++----------- todo.txt | 3 - 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 5d609f3..b7a8412 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -33,7 +33,7 @@ typedef SerialPacketBase SerialPacket; //DOCS: NETWORK_VERSION is used to discern compatible servers and clients -constexpr int NETWORK_VERSION = 20141227; +constexpr int NETWORK_VERSION = -1; union MaxPacket { CharacterPacket a; diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index c4e9842..54d6bfa 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -30,7 +30,7 @@ //TODO: This needs to be smoothed out enum class SerialPacketType { //default: there is something wrong - NONE = 0, + NONE, //------------------------- //ServerPacket @@ -38,12 +38,12 @@ enum class SerialPacketType { //------------------------- //heartbeat - PING = 1, - PONG = 2, + PING, + PONG, //Used for finding available servers - BROADCAST_REQUEST = 3, - BROADCAST_RESPONSE = 4, + BROADCAST_REQUEST, + BROADCAST_RESPONSE, //------------------------- //ClientPacket @@ -51,24 +51,24 @@ enum class SerialPacketType { //------------------------- //Connecting to a server as a client - JOIN_REQUEST = 5, - JOIN_RESPONSE = 6, + JOIN_REQUEST, + JOIN_RESPONSE, //disconnect from the server - DISCONNECT_REQUEST = 7, - DISCONNECT_RESPONSE = 8, - DISCONNECT_FORCED = 9, + DISCONNECT_REQUEST, + DISCONNECT_RESPONSE, + DISCONNECT_FORCED, //load the account - LOGIN_REQUEST = 10, - LOGIN_RESPONSE = 11, + LOGIN_REQUEST, + LOGIN_RESPONSE, //unload the account - LOGOUT_REQUEST = 12, - LOGOUT_RESPONSE = 13, + LOGOUT_REQUEST, + LOGOUT_RESPONSE, //shut down the server - SHUTDOWN_REQUEST = 14, + SHUTDOWN_REQUEST, //------------------------- //RegionPacket @@ -76,8 +76,8 @@ enum class SerialPacketType { //------------------------- //map data - REGION_REQUEST = 15, //NOTE: technically a query - REGION_CONTENT = 16, + REGION_REQUEST, //NOTE: technically a query + REGION_CONTENT, //------------------------- //CharacterPacket @@ -89,22 +89,40 @@ enum class SerialPacketType { //------------------------- //character management - CHARACTER_CREATE = 17, - CHARACTER_DELETE = 18, - CHARACTER_LOAD = 19, - CHARACTER_UNLOAD = 20, + CHARACTER_CREATE, + CHARACTER_DELETE, + CHARACTER_LOAD, + CHARACTER_UNLOAD, //find out info from the server - QUERY_CHARACTER_EXISTS = 21, - QUERY_CHARACTER_STATS = 22, - QUERY_CHARACTER_LOCATION = 23, + QUERY_CHARACTER_EXISTS, + QUERY_CHARACTER_STATS, + QUERY_CHARACTER_LOCATION, //set the info in the server - CHARACTER_SET_ROOM = 24, - CHARACTER_SET_ORIGIN = 25, - CHARACTER_SET_MOTION = 26, + CHARACTER_MOVEMENT, + CHARACTER_ATTACK, - //TODO: enemy management + //admin control +// ADMIN_SET_CHARACTER_ORIGIN, + + //------------------------- + //MonsterPacket + // monster index, + // handle, avatar, hitbox? + // room index, origin, motion + // TODO: attack data + //------------------------- + + MONSTER_CREATE, + MONSTER_DELETE, + + QUERY_MONSTER_EXISTS, //a list of monsters in a room + QUERY_MONSTER_STATS, //statistics of a specific monster type or instance + QUERY_MONSTER_LOCATION, //umm... + + MONSTER_MOVEMENT, //monster movement + MONSTER_ATTACK, //------------------------- //TextPacket @@ -112,20 +130,21 @@ enum class SerialPacketType { //------------------------- //general speech - TEXT_BROADCAST = 27, + TEXT_BROADCAST, //rejection/error messages - JOIN_REJECTION = 28, - LOGIN_REJECTION = 29, - REGION_REJECTION = 30, - CHARACTER_REJECTION = 31, - SHUTDOWN_REJECTION = 32, + JOIN_REJECTION, + LOGIN_REJECTION, + REGION_REJECTION, + CHARACTER_REJECTION, + MONSTER_REJECTION, + SHUTDOWN_REJECTION, //------------------------- //not used //------------------------- - LAST = 33 + LAST }; #endif \ No newline at end of file diff --git a/todo.txt b/todo.txt index 5e87dc8..5b9dc74 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,5 @@ TODO: In need of script APIs (list) * Characters - * Monsters - * Waypoints TODO: Account passwords (list) * backbone account server OR @@ -9,7 +7,6 @@ TODO: Account passwords (list) * ... * salts & hashes -TODO: Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. TODO: Fix shoddy movement TODO: Periodic mass server saves TODO: Remove the big "Shut Down" button (currently broken...) From dc40ee64cf287d6cb21e0353a93a8c42d4e0378d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 13 Jan 2015 00:23:01 +1100 Subject: [PATCH 02/21] common builds cleanly --- .../network/packet_types/monster_packet.cpp | 76 +++++++++++++++++++ .../network/packet_types/monster_packet.hpp | 48 ++++++++++++ common/network/serial_packet.hpp | 8 +- common/network/serial_packet_type.hpp | 2 +- common/network/serial_utility.cpp | 31 ++++++-- 5 files changed, 155 insertions(+), 10 deletions(-) create mode 100644 common/network/packet_types/monster_packet.cpp create mode 100644 common/network/packet_types/monster_packet.hpp diff --git a/common/network/packet_types/monster_packet.cpp b/common/network/packet_types/monster_packet.cpp new file mode 100644 index 0000000..5304550 --- /dev/null +++ b/common/network/packet_types/monster_packet.cpp @@ -0,0 +1,76 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "monster_packet.hpp" + +#include "serial_utility.hpp" + +void serializeMonster(void* buffer, MonsterPacket* packet) { + serialCopy(&buffer, &packet->type, sizeof(SerialPacketType)); + + //identify the monster + serialCopy(&buffer, &packet->monsterIndex, sizeof(int)); + serialCopy(&buffer, packet->handle, PACKET_STRING_SIZE); + serialCopy(&buffer, packet->avatar, PACKET_STRING_SIZE); + + //bounds + serialCopy(&buffer, &packet->bounds.x, sizeof(int)); + serialCopy(&buffer, &packet->bounds.y, sizeof(int)); + serialCopy(&buffer, &packet->bounds.w, sizeof(int)); + serialCopy(&buffer, &packet->bounds.h, sizeof(int)); + + + //location + serialCopy(&buffer, &packet->roomIndex, sizeof(int)); + serialCopy(&buffer, &packet->origin.x, sizeof(double)); + serialCopy(&buffer, &packet->origin.y, sizeof(double)); + serialCopy(&buffer, &packet->motion.x, sizeof(double)); + serialCopy(&buffer, &packet->motion.y, sizeof(double)); + + //attack data + //TODO +} + +void deserializeMonster(void* buffer, MonsterPacket* packet) { + deserialCopy(&buffer, &packet->type, sizeof(SerialPacketType)); + + //identify the monster + deserialCopy(&buffer, &packet->monsterIndex, sizeof(int)); + deserialCopy(&buffer, packet->handle, PACKET_STRING_SIZE); + deserialCopy(&buffer, packet->avatar, PACKET_STRING_SIZE); + + //bounds + deserialCopy(&buffer, &packet->bounds.x, sizeof(int)); + deserialCopy(&buffer, &packet->bounds.y, sizeof(int)); + deserialCopy(&buffer, &packet->bounds.w, sizeof(int)); + deserialCopy(&buffer, &packet->bounds.h, sizeof(int)); + + + //location + deserialCopy(&buffer, &packet->roomIndex, sizeof(int)); + deserialCopy(&buffer, &packet->origin.x, sizeof(double)); + deserialCopy(&buffer, &packet->origin.y, sizeof(double)); + deserialCopy(&buffer, &packet->motion.x, sizeof(double)); + deserialCopy(&buffer, &packet->motion.y, sizeof(double)); + + //attack data + //TODO +} diff --git a/common/network/packet_types/monster_packet.hpp b/common/network/packet_types/monster_packet.hpp new file mode 100644 index 0000000..97ebd38 --- /dev/null +++ b/common/network/packet_types/monster_packet.hpp @@ -0,0 +1,48 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef MONSTERPACKET_HPP_ +#define MONSTERPACKET_HPP_ + +#include "serial_packet_base.hpp" + +#include "bounding_box.hpp" +#include "vector2.hpp" + +struct MonsterPacket : SerialPacketBase { + //identify the monster + int monsterIndex; + char handle[PACKET_STRING_SIZE]; + char avatar[PACKET_STRING_SIZE]; + BoundingBox bounds; + + //location + int roomIndex; + Vector2 origin; + Vector2 motion; + + //TODO: attack data +}; + +void serializeMonster(void* buffer, MonsterPacket* packet); +void deserializeMonster(void* buffer, MonsterPacket* packet); + +#endif \ No newline at end of file diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index b7a8412..fad3dce 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -25,6 +25,7 @@ #include "serial_packet_base.hpp" #include "character_packet.hpp" #include "client_packet.hpp" +#include "monster_packet.hpp" #include "region_packet.hpp" #include "server_packet.hpp" #include "text_packet.hpp" @@ -38,9 +39,10 @@ constexpr int NETWORK_VERSION = -1; union MaxPacket { CharacterPacket a; ClientPacket b; - RegionPacket c; - ServerPacket d; - TextPacket e; + MonsterPacket c; + RegionPacket d; + ServerPacket e; + TextPacket f; }; constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket); diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index 54d6bfa..bfd808c 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -109,7 +109,7 @@ enum class SerialPacketType { //------------------------- //MonsterPacket // monster index, - // handle, avatar, hitbox? + // handle, avatar, hitbox // room index, origin, motion // TODO: attack data //------------------------- diff --git a/common/network/serial_utility.cpp b/common/network/serial_utility.cpp index a0d2c61..e258a9e 100644 --- a/common/network/serial_utility.cpp +++ b/common/network/serial_utility.cpp @@ -24,6 +24,7 @@ //packet types #include "character_packet.hpp" #include "client_packet.hpp" +#include "monster_packet.hpp" #include "region_packet.hpp" #include "server_packet.hpp" #include "text_packet.hpp" @@ -75,16 +76,25 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::QUERY_CHARACTER_EXISTS: case SerialPacketType::QUERY_CHARACTER_STATS: case SerialPacketType::QUERY_CHARACTER_LOCATION: - case SerialPacketType::CHARACTER_SET_ROOM: - case SerialPacketType::CHARACTER_SET_ORIGIN: - case SerialPacketType::CHARACTER_SET_MOTION: + case SerialPacketType::CHARACTER_MOVEMENT: + case SerialPacketType::CHARACTER_ATTACK: serializeCharacter(buffer, static_cast(packet)); break; + case SerialPacketType::MONSTER_CREATE: + case SerialPacketType::MONSTER_DELETE: + case SerialPacketType::QUERY_MONSTER_EXISTS: + case SerialPacketType::QUERY_MONSTER_STATS: + case SerialPacketType::QUERY_MONSTER_LOCATION: + case SerialPacketType::MONSTER_MOVEMENT: + case SerialPacketType::MONSTER_ATTACK: + serializeMonster(buffer, static_cast(packet)); + break; case SerialPacketType::TEXT_BROADCAST: case SerialPacketType::JOIN_REJECTION: case SerialPacketType::LOGIN_REJECTION: case SerialPacketType::REGION_REJECTION: case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::MONSTER_REJECTION: case SerialPacketType::SHUTDOWN_REJECTION: serializeText(buffer, static_cast(packet)); break; @@ -126,16 +136,25 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::QUERY_CHARACTER_EXISTS: case SerialPacketType::QUERY_CHARACTER_STATS: case SerialPacketType::QUERY_CHARACTER_LOCATION: - case SerialPacketType::CHARACTER_SET_ROOM: - case SerialPacketType::CHARACTER_SET_ORIGIN: - case SerialPacketType::CHARACTER_SET_MOTION: + case SerialPacketType::CHARACTER_MOVEMENT: + case SerialPacketType::CHARACTER_ATTACK: deserializeCharacter(buffer, static_cast(packet)); break; + case SerialPacketType::MONSTER_CREATE: + case SerialPacketType::MONSTER_DELETE: + case SerialPacketType::QUERY_MONSTER_EXISTS: + case SerialPacketType::QUERY_MONSTER_STATS: + case SerialPacketType::QUERY_MONSTER_LOCATION: + case SerialPacketType::MONSTER_MOVEMENT: + case SerialPacketType::MONSTER_ATTACK: + deserializeMonster(buffer, static_cast(packet)); + break; case SerialPacketType::TEXT_BROADCAST: case SerialPacketType::JOIN_REJECTION: case SerialPacketType::LOGIN_REJECTION: case SerialPacketType::REGION_REJECTION: case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::MONSTER_REJECTION: case SerialPacketType::SHUTDOWN_REJECTION: deserializeText(buffer, static_cast(packet)); break; From 42662c3f61de3468d5ea8b20d908a6f55867ae97 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 13 Jan 2015 02:04:48 +1100 Subject: [PATCH 03/21] Replaced HandleCharacterSet*() with HandleCharacterMovement() This new method rolls three otherwise similar methods together. There is still a conditional which handles room movements separately, but it's much smoother, and PumpPacketProximity is utilized much more. I've also added a stub for graphical attack data via HandleCharacterAttack() --- server/server_application.hpp | 5 +- server/server_character_methods.cpp | 137 ++++++++-------------------- server/server_logic.cpp | 27 +++--- 3 files changed, 50 insertions(+), 119 deletions(-) diff --git a/server/server_application.hpp b/server/server_application.hpp index 8ed4f24..05a75a6 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -101,9 +101,8 @@ private: void HandleCharacterUnload(CharacterPacket* const); //character movement - void HandleCharacterSetRoom(CharacterPacket* const); - void HandleCharacterSetOrigin(CharacterPacket* const); - void HandleCharacterSetMotion(CharacterPacket* const); + void HandleCharacterMovement(CharacterPacket* const); + void HandleCharacterAttack(CharacterPacket* const); //utility methods void PumpPacket(SerialPacket* const); diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index 910a6cc..bf302b7 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -175,105 +175,15 @@ void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) //character movement //------------------------- -//TODO: ? Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments +//TODO: Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments -void ServerApplication::HandleCharacterSetRoom(CharacterPacket* const argPacket) { +void ServerApplication::HandleCharacterMovement(CharacterPacket* const argPacket) { //get the specified objects AccountData* accountData = accountMgr.Get(argPacket->accountIndex); CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); if (!accountData || !characterData) { - throw(std::runtime_error("Failed to set character room, missing data")); - } - - //get this account's client - ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); - - //check for fraud - if (clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified set character origin targeting uid(" << argPacket->characterIndex << ")" << std::endl; - return; - } - - //check if allowed - if (characterData->GetOwner() != argPacket->accountIndex && !accountData->GetModerator() && !accountData->GetAdministrator()) { - //TODO: send to the client? - std::cerr << "Failed to set character room due to lack of permissions targeting uid(" << argPacket->characterIndex << ")" << std::endl; - return; - } - - //pop from the old room - roomMgr.PopCharacter(characterData); - - //set the character's room, zero it's origin, zero it's motion - characterData->SetRoomIndex(argPacket->roomIndex); - characterData->SetOrigin({0, 0}); - characterData->SetMotion({0, 0}); - - //push to the new room - roomMgr.PushCharacter(characterData); - - //update the clients - CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); - newPacket.type = SerialPacketType::CHARACTER_SET_ROOM; - PumpPacket(&newPacket); -} - -void ServerApplication::HandleCharacterSetOrigin(CharacterPacket* const argPacket) { - //get the specified objects - AccountData* accountData = accountMgr.Get(argPacket->accountIndex); - CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); - - if (!accountData || !characterData) { - throw(std::runtime_error("Failed to set character origin, missing data")); - } - - //get this account's client - ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); - - //check for fraud - if (clientData->GetAddress() != argPacket->srcAddress) { - std::cerr << "Falsified set character origin targeting uid(" << argPacket->characterIndex << ")" << std::endl; - return; - } - - //check if allowed - if (characterData->GetOwner() != argPacket->accountIndex && !accountData->GetModerator() && !accountData->GetAdministrator()) { - //TODO: send to the client? - std::cerr << "Failed to set character origin due to lack of permissions targeting uid(" << argPacket->characterIndex << ")" << std::endl; - return; - } - - //set the character's origin, zero it's motion - characterData->SetOrigin(argPacket->origin); - characterData->SetMotion({0, 0}); - - //update the clients - CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); - newPacket.type = SerialPacketType::CHARACTER_SET_ORIGIN; - PumpPacket(&newPacket); -} - -void ServerApplication::HandleCharacterSetMotion(CharacterPacket* const argPacket) { - //get the specified objects - AccountData* accountData = accountMgr.Get(argPacket->accountIndex); - - if (!accountData) { - std::ostringstream msg; - msg << "Failed to set character motion, missing account: Index " << argPacket->accountIndex << "; "; - msg << "Number of accounts loaded: " << accountMgr.GetContainer()->size(); - throw(std::runtime_error(msg.str())); - } - - CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); - - if (!characterData) { - std::ostringstream msg; - msg << "Failed to set character motion, missing character: Index " << argPacket->characterIndex << "; "; - msg << "Number of characters loaded: " << characterMgr.GetContainer()->size(); - throw(std::runtime_error(msg.str())); + throw(std::runtime_error("Failed to move a character, missing data")); } //get this account's client @@ -292,13 +202,38 @@ void ServerApplication::HandleCharacterSetMotion(CharacterPacket* const argPacke return; } - //set the character's origin and motion - characterData->SetOrigin(argPacket->origin); - characterData->SetMotion(argPacket->motion); + //check if moving rooms + if (characterData->GetRoomIndex() != argPacket->roomIndex) { + //delete from the old room + CharacterPacket newPacket; + CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + newPacket.type = SerialPacketType::CHARACTER_DELETE; + PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); - //update the clients - CharacterPacket newPacket; - CopyCharacterToPacket(&newPacket, argPacket->characterIndex); - newPacket.type = SerialPacketType::CHARACTER_SET_MOTION; - PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + //move the character between rooms + roomMgr.PopCharacter(characterData); + characterData->SetRoomIndex(argPacket->roomIndex); + roomMgr.PushCharacter(characterData); + + //create in the new room + CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + newPacket.type = SerialPacketType::CHARACTER_CREATE; + PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + } + //if not moving between rooms + else { + //set the character's origin and motion + characterData->SetOrigin(argPacket->origin); + characterData->SetMotion(argPacket->motion); + + //update the clients + CharacterPacket newPacket; + CopyCharacterToPacket(&newPacket, argPacket->characterIndex); + newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; + PumpPacketProximity(&newPacket, characterData->GetRoomIndex(), characterData->GetOrigin(), -1); + } } + +void ServerApplication::HandleCharacterAttack(CharacterPacket* const) { + //TODO: bounce graphical attack data +} \ No newline at end of file diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 802c8c9..443adb2 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -277,27 +277,24 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { HandleCharacterUnload(static_cast(argPacket)); break; - //character movement - case SerialPacketType::CHARACTER_SET_ROOM: - HandleCharacterSetRoom(static_cast(argPacket)); +/* case SerialPacketType::QUERY_CHARACTER_EXISTS: + // break; - case SerialPacketType::CHARACTER_SET_ORIGIN: - HandleCharacterSetOrigin(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_SET_MOTION: - HandleCharacterSetMotion(static_cast(argPacket)); - break; -/* case SerialPacketType::QUERY_CHARACTER_STATS: -// HandleCharacterStatsRequest(static_cast(argPacket)); + // break; case SerialPacketType::QUERY_CHARACTER_LOCATION: -// HandleCharacterStatsRequest(static_cast(argPacket)); + // break; - case SerialPacketType::TEXT_BROADCAST: -// HandleCharacterStatsRequest(static_cast(argPacket)); +*/ + //character movement + case SerialPacketType::CHARACTER_MOVEMENT: + HandleCharacterMovement(static_cast(argPacket)); break; - + case SerialPacketType::CHARACTER_ATTACK: + HandleCharacterAttack(static_cast(argPacket)); + break; +/* //enemy management //TODO: enemy management From be906942342dfbe37ab5f16b800f749797d9c247 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 15 Jan 2015 23:32:04 +1100 Subject: [PATCH 04/21] Added network tweaks to client; project builds cleanly --- client/scenes/in_world.cpp | 75 ++++++-------------------------------- client/scenes/in_world.hpp | 7 ++-- 2 files changed, 15 insertions(+), 67 deletions(-) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index ec03408..3bfc456 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -159,7 +159,7 @@ void InWorld::Update() { //process the collisions if (localCharacter->ProcessCollisionGrid(boxList)) { localCharacter->CorrectSprite(); - SendLocalCharacterMotion(); + SendLocalCharacterMovement(); } //update the camera @@ -267,7 +267,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { //set the info localCharacter->SetMotion(motion); localCharacter->CorrectSprite(); - SendLocalCharacterMotion(); + SendLocalCharacterMovement(); } void InWorld::KeyUp(SDL_KeyboardEvent const& key) { @@ -313,7 +313,7 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { //set the info localCharacter->SetMotion(motion); localCharacter->CorrectSprite(); - SendLocalCharacterMotion(); + SendLocalCharacterMovement(); } //------------------------- @@ -358,14 +358,11 @@ void InWorld::HandlePacket(SerialPacket* const argPacket) { break; //character movement - case SerialPacketType::CHARACTER_SET_ROOM: - HandleCharacterSetRoom(static_cast(argPacket)); + case SerialPacketType::CHARACTER_MOVEMENT: + HandleCharacterMovement(static_cast(argPacket)); break; - case SerialPacketType::CHARACTER_SET_ORIGIN: - HandleCharacterSetOrigin(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_SET_MOTION: - HandleCharacterSetMotion(static_cast(argPacket)); + case SerialPacketType::CHARACTER_ATTACK: + HandleCharacterAttack(static_cast(argPacket)); break; //rejection messages @@ -638,43 +635,7 @@ void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { std::cout << "Query, total: " << characterMap.size() << std::endl; } -void InWorld::HandleCharacterSetRoom(CharacterPacket* const argPacket) { - //someone else's character - if (argPacket->characterIndex != characterIndex) { - characterMap.erase(argPacket->characterIndex); - return; - } - - //this character is moving between rooms - roomIndex = argPacket->roomIndex; - - //set the character's info - localCharacter->SetOrigin(argPacket->origin); - localCharacter->SetMotion(argPacket->motion); - localCharacter->CorrectSprite(); - - //clear the old room's data - regionPager.UnloadAll(); - monsterMap.clear(); - - //use the jenky pattern for std::map to skip this player's character - for (std::map::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) { - if (it->first != characterIndex) { - it = characterMap.erase(it); - } - else { - ++it; - } - } - - //request the info on characters in this room - CharacterPacket newPacket; - newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; - newPacket.roomIndex = roomIndex; - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::HandleCharacterSetOrigin(CharacterPacket* const argPacket) { +void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { //TODO: Authentication if (argPacket->characterIndex == characterIndex) { return; @@ -690,20 +651,8 @@ void InWorld::HandleCharacterSetOrigin(CharacterPacket* const argPacket) { } } -void InWorld::HandleCharacterSetMotion(CharacterPacket* const argPacket) { - //TODO: Authentication - if (argPacket->characterIndex == characterIndex) { - return; - } - - //check that this character exists - std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); - if (characterIt != characterMap.end()) { - //set the origin and motion - characterIt->second.SetOrigin(argPacket->origin); - characterIt->second.SetMotion(argPacket->motion); - characterIt->second.CorrectSprite(); - } +void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { + //TODO: attack animation } //------------------------- @@ -711,9 +660,9 @@ void InWorld::HandleCharacterSetMotion(CharacterPacket* const argPacket) { //------------------------- //TODO: add a "movement" packet type -void InWorld::SendLocalCharacterMotion() { +void InWorld::SendLocalCharacterMovement() { CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_SET_MOTION; + newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; newPacket.accountIndex = accountIndex; newPacket.characterIndex = characterIndex; diff --git a/client/scenes/in_world.hpp b/client/scenes/in_world.hpp index 7ce1288..d328c6d 100644 --- a/client/scenes/in_world.hpp +++ b/client/scenes/in_world.hpp @@ -96,12 +96,11 @@ protected: void HandleCharacterCreate(CharacterPacket* const); void HandleCharacterDelete(CharacterPacket* const); void HandleCharacterQueryExists(CharacterPacket* const); - void HandleCharacterSetRoom(CharacterPacket* const); - void HandleCharacterSetOrigin(CharacterPacket* const); - void HandleCharacterSetMotion(CharacterPacket* const); + void HandleCharacterMovement(CharacterPacket* const); + void HandleCharacterAttack(CharacterPacket* const); //player movement - void SendLocalCharacterMotion(); + void SendLocalCharacterMovement(); std::list GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight); //indexes From 9b2e78a68e9772f4289e4f3c32c352500c83eef6 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 17 Jan 2015 16:57:04 +1100 Subject: [PATCH 05/21] Split the scenes directory into gameplay_scenes and menu_scenes --- client/{scenes => }/base_scene.cpp | 0 client/{scenes => }/base_scene.hpp | 0 .../{scenes => gameplay_scenes}/in_world.cpp | 0 .../{scenes => gameplay_scenes}/in_world.hpp | 0 client/{scenes => gameplay_scenes}/makefile | 0 client/makefile | 5 ++- .../disconnected_screen.cpp | 0 .../disconnected_screen.hpp | 0 client/{scenes => menu_scenes}/lobby_menu.cpp | 0 client/{scenes => menu_scenes}/lobby_menu.hpp | 0 client/{scenes => menu_scenes}/main_menu.cpp | 0 client/{scenes => menu_scenes}/main_menu.hpp | 0 client/menu_scenes/makefile | 37 +++++++++++++++++++ .../{scenes => menu_scenes}/options_menu.cpp | 0 .../{scenes => menu_scenes}/options_menu.hpp | 0 .../{scenes => menu_scenes}/splash_screen.cpp | 0 .../{scenes => menu_scenes}/splash_screen.hpp | 0 17 files changed, 40 insertions(+), 2 deletions(-) rename client/{scenes => }/base_scene.cpp (100%) rename client/{scenes => }/base_scene.hpp (100%) rename client/{scenes => gameplay_scenes}/in_world.cpp (100%) rename client/{scenes => gameplay_scenes}/in_world.hpp (100%) rename client/{scenes => gameplay_scenes}/makefile (100%) rename client/{scenes => menu_scenes}/disconnected_screen.cpp (100%) rename client/{scenes => menu_scenes}/disconnected_screen.hpp (100%) rename client/{scenes => menu_scenes}/lobby_menu.cpp (100%) rename client/{scenes => menu_scenes}/lobby_menu.hpp (100%) rename client/{scenes => menu_scenes}/main_menu.cpp (100%) rename client/{scenes => menu_scenes}/main_menu.hpp (100%) create mode 100644 client/menu_scenes/makefile rename client/{scenes => menu_scenes}/options_menu.cpp (100%) rename client/{scenes => menu_scenes}/options_menu.hpp (100%) rename client/{scenes => menu_scenes}/splash_screen.cpp (100%) rename client/{scenes => menu_scenes}/splash_screen.hpp (100%) diff --git a/client/scenes/base_scene.cpp b/client/base_scene.cpp similarity index 100% rename from client/scenes/base_scene.cpp rename to client/base_scene.cpp diff --git a/client/scenes/base_scene.hpp b/client/base_scene.hpp similarity index 100% rename from client/scenes/base_scene.hpp rename to client/base_scene.hpp diff --git a/client/scenes/in_world.cpp b/client/gameplay_scenes/in_world.cpp similarity index 100% rename from client/scenes/in_world.cpp rename to client/gameplay_scenes/in_world.cpp diff --git a/client/scenes/in_world.hpp b/client/gameplay_scenes/in_world.hpp similarity index 100% rename from client/scenes/in_world.hpp rename to client/gameplay_scenes/in_world.hpp diff --git a/client/scenes/makefile b/client/gameplay_scenes/makefile similarity index 100% rename from client/scenes/makefile rename to client/gameplay_scenes/makefile diff --git a/client/makefile b/client/makefile index 68ce8d9..b931b13 100644 --- a/client/makefile +++ b/client/makefile @@ -1,5 +1,5 @@ #include directories -INCLUDES+=. client_utilities entities scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities +INCLUDES+=. client_utilities entities gameplay_scenes menu_scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities #libraries #the order of the $(LIBS) is important, at least for MinGW @@ -27,7 +27,8 @@ OUT=$(addprefix $(OUTDIR)/,client) all: $(OBJ) $(OUT) $(MAKE) -C client_utilities $(MAKE) -C entities - $(MAKE) -C scenes + $(MAKE) -C gameplay_scenes + $(MAKE) -C menu_scenes $(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS) $(OBJ): | $(OBJDIR) diff --git a/client/scenes/disconnected_screen.cpp b/client/menu_scenes/disconnected_screen.cpp similarity index 100% rename from client/scenes/disconnected_screen.cpp rename to client/menu_scenes/disconnected_screen.cpp diff --git a/client/scenes/disconnected_screen.hpp b/client/menu_scenes/disconnected_screen.hpp similarity index 100% rename from client/scenes/disconnected_screen.hpp rename to client/menu_scenes/disconnected_screen.hpp diff --git a/client/scenes/lobby_menu.cpp b/client/menu_scenes/lobby_menu.cpp similarity index 100% rename from client/scenes/lobby_menu.cpp rename to client/menu_scenes/lobby_menu.cpp diff --git a/client/scenes/lobby_menu.hpp b/client/menu_scenes/lobby_menu.hpp similarity index 100% rename from client/scenes/lobby_menu.hpp rename to client/menu_scenes/lobby_menu.hpp diff --git a/client/scenes/main_menu.cpp b/client/menu_scenes/main_menu.cpp similarity index 100% rename from client/scenes/main_menu.cpp rename to client/menu_scenes/main_menu.cpp diff --git a/client/scenes/main_menu.hpp b/client/menu_scenes/main_menu.hpp similarity index 100% rename from client/scenes/main_menu.hpp rename to client/menu_scenes/main_menu.hpp diff --git a/client/menu_scenes/makefile b/client/menu_scenes/makefile new file mode 100644 index 0000000..24dfb60 --- /dev/null +++ b/client/menu_scenes/makefile @@ -0,0 +1,37 @@ +#config +INCLUDES+=. .. ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../common/utilities +LIBS+= +CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) + +#source +CXXSRC=$(wildcard *.cpp) + +#objects +OBJDIR=obj +OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) + +#output +OUTDIR=.. +OUT=$(addprefix $(OUTDIR)/,client.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/client/scenes/options_menu.cpp b/client/menu_scenes/options_menu.cpp similarity index 100% rename from client/scenes/options_menu.cpp rename to client/menu_scenes/options_menu.cpp diff --git a/client/scenes/options_menu.hpp b/client/menu_scenes/options_menu.hpp similarity index 100% rename from client/scenes/options_menu.hpp rename to client/menu_scenes/options_menu.hpp diff --git a/client/scenes/splash_screen.cpp b/client/menu_scenes/splash_screen.cpp similarity index 100% rename from client/scenes/splash_screen.cpp rename to client/menu_scenes/splash_screen.cpp diff --git a/client/scenes/splash_screen.hpp b/client/menu_scenes/splash_screen.hpp similarity index 100% rename from client/scenes/splash_screen.hpp rename to client/menu_scenes/splash_screen.hpp From 7356e8ae77b5dbe5df60ee0f8b3c65d38ce3bdbb Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 17 Jan 2015 21:46:12 +1100 Subject: [PATCH 06/21] Removed the dependencies on utility.*pp --- client/scenes/in_world.cpp | 5 +-- client/scenes/lobby_menu.cpp | 13 +++++--- common/utilities/utility.cpp | 48 --------------------------- common/utilities/utility.hpp | 34 ------------------- server/server_logic.cpp | 3 +- server/server_utilities/makefile | 2 +- server/server_utilities/sql_tools.cpp | 8 ++--- 7 files changed, 18 insertions(+), 95 deletions(-) delete mode 100644 common/utilities/utility.cpp delete mode 100644 common/utilities/utility.hpp diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index ec03408..42f35a2 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -22,7 +22,6 @@ #include "in_world.hpp" #include "channels.hpp" -#include "utility.hpp" #include "terminal_error.hpp" #include @@ -197,7 +196,9 @@ void InWorld::Render(SDL_Surface* const screen) { //draw UI disconnectButton.DrawTo(screen); shutDownButton.DrawTo(screen); - font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0); + std::ostringstream msg; + msg << fps.GetFrameRate(); + font.DrawStringTo(msg.str(), screen, 0, 0); } //------------------------- diff --git a/client/scenes/lobby_menu.cpp b/client/scenes/lobby_menu.cpp index 0776242..befc6f5 100644 --- a/client/scenes/lobby_menu.cpp +++ b/client/scenes/lobby_menu.cpp @@ -22,9 +22,9 @@ #include "lobby_menu.hpp" #include "channels.hpp" -#include "utility.hpp" #include +#include //------------------------- //Public access members @@ -123,7 +123,9 @@ void LobbyMenu::Render(SDL_Surface* const screen) { font.DrawStringTo(serverInfo[i].name, screen, listBox.x, listBox.y + i*listBox.h); //draw the player count - font.DrawStringTo(to_string_custom(serverInfo[i].playerCount), screen, listBox.x + listBox.w, listBox.y + i*listBox.h); + std::ostringstream msg; + msg << serverInfo[i].playerCount; + font.DrawStringTo(msg.str(), screen, listBox.x + listBox.w, listBox.y + i*listBox.h); //compatible? if (!serverInfo[i].compatible) { @@ -210,8 +212,11 @@ void LobbyMenu::HandlePacket(SerialPacket* const argPacket) { break; //handle errors - default: - throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(static_cast(argPacket->type)) )); + default: { + std::ostringstream msg; + msg << "Unknown SerialPacketType encountered in LobbyMenu: " << static_cast(argPacket->type); + throw(std::runtime_error( msg.str() )); + } break; } } diff --git a/common/utilities/utility.cpp b/common/utilities/utility.cpp deleted file mode 100644 index 64b135b..0000000 --- a/common/utilities/utility.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013-2015 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#include "utility.hpp" - -#include - -std::string truncatePath(std::string pathname) { - return std::string( - std::find_if( - pathname.rbegin(), - pathname.rend(), - [](char ch) -> bool { - //windows & unix tested - return ch == '/' || ch == '\\'; - }).base(), - pathname.end()); -} - -std::string to_string_custom(int i) { - char buffer[20]; - snprintf(buffer, 20, "%d", i); - return std::string(buffer); -} - -int to_integer_custom(std::string s) { - int ret = 0; - sscanf(s.c_str(), "%d", &ret); - return ret; -} \ No newline at end of file diff --git a/common/utilities/utility.hpp b/common/utilities/utility.hpp deleted file mode 100644 index 53cb426..0000000 --- a/common/utilities/utility.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013-2015 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#ifndef UTILITY_HPP_ -#define UTILITY_HPP_ - -#include - -std::string truncatePath(std::string pathname); - -//fixing known bugs in g++ -std::string to_string_custom(int i); - -int to_integer_custom(std::string); - -#endif diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 802c8c9..96ca1fe 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -23,7 +23,6 @@ //utility functions #include "sql_tools.hpp" -#include "utility.hpp" //std & STL #include @@ -307,7 +306,7 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { default: { std::ostringstream msg; msg << "Unknown SerialPacketType encountered in the server: "; - msg << to_string_custom(static_cast(argPacket->type)); + msg << static_cast(argPacket->type); throw(std::runtime_error(msg.str())); } break; diff --git a/server/server_utilities/makefile b/server/server_utilities/makefile index f24e1ba..8d12afe 100644 --- a/server/server_utilities/makefile +++ b/server/server_utilities/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../../common/utilities +INCLUDES+=. LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/server/server_utilities/sql_tools.cpp b/server/server_utilities/sql_tools.cpp index d83acba..78e1065 100644 --- a/server/server_utilities/sql_tools.cpp +++ b/server/server_utilities/sql_tools.cpp @@ -21,10 +21,9 @@ */ #include "sql_tools.hpp" -#include "utility.hpp" - #include #include +#include #include int runSQLScript(sqlite3* db, std::string fname, int (*callback)(void*,int,char**,char**), void* argPtr) { @@ -42,9 +41,10 @@ int runSQLScript(sqlite3* db, std::string fname, int (*callback)(void*,int,char* int ret = sqlite3_exec(db, script.c_str(), callback, argPtr, &errmsg); if (ret != SQLITE_OK) { //handle any errors received from the SQL - std::runtime_error e(std::string() + "SQL Script Error " + to_string_custom(ret) + ": " + errmsg); + std::ostringstream msg; + msg << "SQL Script Error " << ret << ": " << errmsg; free(errmsg); - throw(e); + throw(std::runtime_error( msg.str() )); } return ret; } \ No newline at end of file From dacb8df674766c1c720d427fe11d5017f9c6b68a Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 17 Jan 2015 22:09:14 +1100 Subject: [PATCH 07/21] Split in_world.cpp into three files --- client/gameplay_scenes/in_world.cpp | 704 ------------------ client/gameplay_scenes/in_world_entities.cpp | 196 +++++ .../gameplay_scenes/in_world_networking.cpp | 248 ++++++ .../in_world_scene_components.cpp | 317 ++++++++ 4 files changed, 761 insertions(+), 704 deletions(-) delete mode 100644 client/gameplay_scenes/in_world.cpp create mode 100644 client/gameplay_scenes/in_world_entities.cpp create mode 100644 client/gameplay_scenes/in_world_networking.cpp create mode 100644 client/gameplay_scenes/in_world_scene_components.cpp diff --git a/client/gameplay_scenes/in_world.cpp b/client/gameplay_scenes/in_world.cpp deleted file mode 100644 index 3bfc456..0000000 --- a/client/gameplay_scenes/in_world.cpp +++ /dev/null @@ -1,704 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013-2015 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#include "in_world.hpp" - -#include "channels.hpp" -#include "utility.hpp" - -#include "terminal_error.hpp" -#include -#include -#include -#include -#include - -//------------------------- -//these should've come standard -//------------------------- - -bool operator==(IPaddress lhs, IPaddress rhs) { - return lhs.host == rhs.host && lhs.port == rhs.port; -} - -bool operator!=(IPaddress lhs, IPaddress rhs) { - return !(lhs == rhs); -} - -//------------------------- -//Public access members -//------------------------- - -InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): - clientIndex(*argClientIndex), - accountIndex(*argAccountIndex) -{ - //setup the utility objects - buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); - buttonImage.SetClipH(buttonImage.GetClipH()/3); - font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp"); - - //pass the utility objects - disconnectButton.SetImage(&buttonImage); - disconnectButton.SetFont(&font); - shutDownButton.SetImage(&buttonImage); - shutDownButton.SetFont(&font); - - //set the button positions - disconnectButton.SetX(50); - disconnectButton.SetY(50 + buttonImage.GetClipH() * 0); - shutDownButton.SetX(50); - shutDownButton.SetY(50 + buttonImage.GetClipH() * 1); - - //set the button texts - disconnectButton.SetText("Disconnect"); - shutDownButton.SetText("Shut Down"); - - //load the tilesheet - //TODO: add the tilesheet to the map system - //TODO: Tile size and tile sheet should be loaded elsewhere - tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32); - - //Send the character data - //TODO: login scene, prompt, etc. - CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_LOAD; - 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); - - //query the world state - memset(&newPacket, 0, MAX_PACKET_SIZE); - newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; - network.SendTo(Channels::SERVER, &newPacket); - - //set the camera's values - camera.width = GetScreen()->w; - camera.height = GetScreen()->h; - - //debug - // -} - -InWorld::~InWorld() { - //unload the local data - characterMap.clear(); - monsterMap.clear(); -} - -//------------------------- -//Frame loop -//------------------------- - -void InWorld::FrameStart() { - // -} - -void InWorld::Update() { - //create and zero the buffer - SerialPacket* packetBuffer = reinterpret_cast(new char[MAX_PACKET_SIZE]); - memset(packetBuffer, 0, MAX_PACKET_SIZE); - - try { - //suck in and process all waiting packets - while(network.Receive(packetBuffer)) { - HandlePacket(packetBuffer); - } - } - catch(terminal_error& e) { - throw(e); - } - catch(std::exception& e) { - std::cerr << "HandlePacket Error: " << e.what() << std::endl; - } - - //free the buffer - delete reinterpret_cast(packetBuffer); - - //heartbeat system - CheckHeartBeat(); - - //update all entities - for (auto& it : characterMap) { - it.second.Update(); - } - for (auto& it : monsterMap) { - it.second.Update(); - } - - //update the map - UpdateMap(); - - //skip the rest without a local character - if (!localCharacter) { - return; - } - - //get the collidable boxes - std::list boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH()); - - //process the collisions - if (localCharacter->ProcessCollisionGrid(boxList)) { - localCharacter->CorrectSprite(); - SendLocalCharacterMovement(); - } - - //update the camera - camera.x = localCharacter->GetOrigin().x - camera.marginX; - camera.y = localCharacter->GetOrigin().y - camera.marginY; -} - -void InWorld::FrameEnd() { - // -} - -void InWorld::RenderFrame() { - SDL_FillRect(GetScreen(), 0, 0); - Render(GetScreen()); - SDL_Flip(GetScreen()); - fps.Calculate(); -} - -void InWorld::Render(SDL_Surface* const screen) { - //draw the map - for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { - tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y); - } - - //draw the entities - for (auto& it : characterMap) { - //TODO: depth ordering - it.second.DrawTo(screen, camera.x, camera.y); - } - for (auto& it : monsterMap) { - //TODO: depth ordering - it.second.DrawTo(screen, camera.x, camera.y); - } - - //draw UI - disconnectButton.DrawTo(screen); - shutDownButton.DrawTo(screen); - font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0); -} - -//------------------------- -//Event handlers -//------------------------- - -void InWorld::QuitEvent() { - //two-step logout - SendDisconnectRequest(); - SetNextScene(SceneList::QUIT); -} - -void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) { - disconnectButton.MouseMotion(motion); - shutDownButton.MouseMotion(motion); -} - -void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) { - disconnectButton.MouseButtonDown(button); - shutDownButton.MouseButtonDown(button); -} - -void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) { - if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { - SendLogoutRequest(); - } - if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { - SendShutdownRequest(); - } -} - -void InWorld::KeyDown(SDL_KeyboardEvent const& key) { - //hotkeys - switch(key.keysym.sym) { - case SDLK_ESCAPE: - //TODO: the escape key should actually control menus and stuff - SendLogoutRequest(); - return; - } - - //character movement - if (!localCharacter) { - return; - } - Vector2 motion = localCharacter->GetMotion(); - switch(key.keysym.sym) { - case SDLK_w: - motion.y -= CHARACTER_WALKING_SPEED; - break; - case SDLK_a: - motion.x -= CHARACTER_WALKING_SPEED; - break; - case SDLK_s: - motion.y += CHARACTER_WALKING_SPEED; - break; - case SDLK_d: - motion.x += CHARACTER_WALKING_SPEED; - break; - default: - //DOCS: prevents wrong keys screwing with character movement - return; - } - //handle diagonals - if (motion.x != 0 && motion.y != 0) { - motion *= CHARACTER_WALKING_MOD; - } - //set the info - localCharacter->SetMotion(motion); - localCharacter->CorrectSprite(); - SendLocalCharacterMovement(); -} - -void InWorld::KeyUp(SDL_KeyboardEvent const& key) { - //character movement - if (!localCharacter) { - return; - } - Vector2 motion = localCharacter->GetMotion(); - switch(key.keysym.sym) { - case SDLK_w: - motion.y = std::min(0.0, motion.y += CHARACTER_WALKING_SPEED); - break; - case SDLK_a: - motion.x = std::min(0.0, motion.x += CHARACTER_WALKING_SPEED); - break; - case SDLK_s: - motion.y = std::max(0.0, motion.y -= CHARACTER_WALKING_SPEED); - break; - case SDLK_d: - motion.x = std::max(0.0, motion.x -= CHARACTER_WALKING_SPEED); - break; - default: - //DOCS: prevents wrong keys screwing with character movement - return; - } - //BUGFIX: reset cardinal direction speed on key release - if (motion.x > 0) { - motion.x = CHARACTER_WALKING_SPEED; - } - else if (motion.x < 0) { - motion.x = -CHARACTER_WALKING_SPEED; - } - if (motion.y > 0) { - motion.y = CHARACTER_WALKING_SPEED; - } - else if (motion.y < 0) { - motion.y = -CHARACTER_WALKING_SPEED; - } - //handle diagonals - if (motion.x != 0 && motion.y != 0) { - motion *= CHARACTER_WALKING_MOD; - } - //set the info - localCharacter->SetMotion(motion); - localCharacter->CorrectSprite(); - SendLocalCharacterMovement(); -} - -//------------------------- -//Basic connections -//------------------------- - -void InWorld::HandlePacket(SerialPacket* const argPacket) { - switch(argPacket->type) { - //heartbeat system - case SerialPacketType::PING: - HandlePing(static_cast(argPacket)); - break; - case SerialPacketType::PONG: - HandlePong(static_cast(argPacket)); - break; - - //game server connections - case SerialPacketType::LOGOUT_RESPONSE: - HandleLogoutResponse(static_cast(argPacket)); - break; - case SerialPacketType::DISCONNECT_RESPONSE: - HandleDisconnectResponse(static_cast(argPacket)); - break; - case SerialPacketType::DISCONNECT_FORCED: - HandleDisconnectForced(static_cast(argPacket)); - break; - - //map management - case SerialPacketType::REGION_CONTENT: - HandleRegionContent(static_cast(argPacket)); - break; - - //character management - case SerialPacketType::CHARACTER_CREATE: - HandleCharacterCreate(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(static_cast(argPacket)); - break; - case SerialPacketType::QUERY_CHARACTER_EXISTS: - HandleCharacterQueryExists(static_cast(argPacket)); - break; - - //character movement - case SerialPacketType::CHARACTER_MOVEMENT: - HandleCharacterMovement(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_ATTACK: - HandleCharacterAttack(static_cast(argPacket)); - break; - - //rejection messages - case SerialPacketType::REGION_REJECTION: - case SerialPacketType::CHARACTER_REJECTION: - throw(terminal_error(static_cast(argPacket)->text)); - break; - case SerialPacketType::SHUTDOWN_REJECTION: - throw(std::runtime_error(static_cast(argPacket)->text)); - break; - - //errors - default: { - std::ostringstream msg; - msg << "Unknown SerialPacketType encountered in InWorld: " << static_cast(argPacket->type); - throw(std::runtime_error(msg.str())); - } - break; - } -} - -void InWorld::HandlePing(ServerPacket* const argPacket) { - ServerPacket newPacket; - newPacket.type = SerialPacketType::PONG; - network.SendTo(argPacket->srcAddress, &newPacket); -} - -void InWorld::HandlePong(ServerPacket* const argPacket) { - if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) { - throw(std::runtime_error("Heartbeat message received from an unknown source")); - } - attemptedBeats = 0; - lastBeat = Clock::now(); -} - -//------------------------- -//Connection control -//------------------------- - -void InWorld::SendLogoutRequest() { - ClientPacket newPacket; - - //send a logout request - newPacket.type = SerialPacketType::LOGOUT_REQUEST; - newPacket.accountIndex = accountIndex; - - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::SendDisconnectRequest() { - ClientPacket newPacket; - - //send a disconnect request - newPacket.type = SerialPacketType::DISCONNECT_REQUEST; - newPacket.clientIndex = clientIndex; - - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::SendShutdownRequest() { - ClientPacket newPacket; - - //send a shutdown request - newPacket.type = SerialPacketType::SHUTDOWN_REQUEST; - newPacket.accountIndex = accountIndex; - - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::HandleLogoutResponse(ClientPacket* const argPacket) { - if (localCharacter) { - characterMap.erase(characterIndex); - localCharacter = nullptr; - } - - accountIndex = -1; - characterIndex = -1; - - //reset the camera - camera.marginX = camera.marginY = 0; - - //because, why not? I guess... - SendDisconnectRequest(); -} - -void InWorld::HandleDisconnectResponse(ClientPacket* const argPacket) { - HandleLogoutResponse(argPacket);//shortcut - SetNextScene(SceneList::DISCONNECTEDSCREEN); - ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have successfully logged out"; -} - -void InWorld::HandleDisconnectForced(ClientPacket* const argPacket) { - HandleDisconnectResponse(argPacket);//shortcut - SetNextScene(SceneList::DISCONNECTEDSCREEN); - ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server"; -} - -void InWorld::CheckHeartBeat() { - //check the connection (heartbeat) - if (Clock::now() - lastBeat > std::chrono::seconds(3)) { - if (attemptedBeats > 2) { - //escape to the disconnect screen - SendDisconnectRequest(); - SetNextScene(SceneList::DISCONNECTEDSCREEN); - ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server"; - } - else { - ServerPacket newPacket; - newPacket.type = SerialPacketType::PING; - network.SendTo(Channels::SERVER, &newPacket); - - attemptedBeats++; - lastBeat = Clock::now(); - } - } -} - -//------------------------- -//map management -//------------------------- - -void InWorld::SendRegionRequest(int roomIndex, int x, int y) { - RegionPacket packet; - - //pack the region's data - packet.type = SerialPacketType::REGION_REQUEST; - packet.roomIndex = roomIndex; - packet.x = x; - packet.y = y; - - network.SendTo(Channels::SERVER, &packet); -} - -void InWorld::HandleRegionContent(RegionPacket* const argPacket) { - //replace existing regions - regionPager.UnloadIf([&](Region const& region) -> bool { - return region.GetX() == argPacket->x && region.GetY() == argPacket->y; - }); - regionPager.PushRegion(argPacket->region); - - //clean up after the serial code - delete argPacket->region; - argPacket->region = nullptr; -} - -void InWorld::UpdateMap() { - if (roomIndex == -1) { - return; - } - - //these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1) - int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH; - int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH; - - int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT; - int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT; - - //prune distant regions - regionPager.GetContainer()->remove_if([&](Region const& region) -> bool { - return region.GetX() < xStart || region.GetX() > xEnd || region.GetY() < yStart || region.GetY() > yEnd; - }); - - //request empty regions within this zone - for (int i = xStart; i <= xEnd; i += REGION_WIDTH) { - for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) { - if (!regionPager.FindRegion(i, j)) { - SendRegionRequest(roomIndex, i, j); - } - } - } -} - -//------------------------- -//entity management -//------------------------- - -//DOCS: preexisting characters will result in query responses -//DOCS: new characters will result in create messages -//DOCS: this client's character will exist in both (skipped) - -void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { - //prevent double message - if (characterMap.find(argPacket->characterIndex) != characterMap.end()) { - std::ostringstream msg; - msg << "Double character creation event; "; - msg << "Index: " << argPacket->characterIndex << "; "; - msg << "Handle: " << argPacket->handle; - throw(std::runtime_error(msg.str())); - } - - //implicity create and retrieve the entity - BaseCharacter* character = &characterMap[argPacket->characterIndex]; - - //fill the character's info - character->SetOrigin(argPacket->origin); - character->SetMotion(argPacket->motion); - character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); - character->SetHandle(argPacket->handle); - character->SetAvatar(argPacket->avatar); - character->SetOwner(argPacket->accountIndex); - character->CorrectSprite(); - - //check for this player's character - if (character->GetOwner() == accountIndex) { - localCharacter = static_cast(character); - - //focus the camera on this character - camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2); - camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2); - - //focus on this character's info - characterIndex = argPacket->characterIndex; - roomIndex = argPacket->roomIndex; - } - - //debug - std::cout << "Create, total: " << characterMap.size() << std::endl; -} - -void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { - //ignore if this character doesn't exist - std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); - if (characterIt == characterMap.end()) { - return; - } - - //check for this player's character - if ((*characterIt).second.GetOwner() == accountIndex) { - localCharacter = nullptr; - - //clear the camera - camera.marginX = 0; - camera.marginY = 0; - - //clear the room - roomIndex = -1; - } - - //remove this character - characterMap.erase(characterIt); - - //debug - std::cout << "Delete, total: " << characterMap.size() << std::endl; -} - -void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { - //prevent a double message about this player's character - if (argPacket->accountIndex == accountIndex) { - return; - } - - //ignore characters in a different room (sub-optimal) - if (argPacket->roomIndex != roomIndex) { - return; - } - - //implicitly construct the character if it doesn't exist - BaseCharacter* character = &characterMap[argPacket->characterIndex]; - - //set/update the character's info - character->SetOrigin(argPacket->origin); - character->SetMotion(argPacket->motion); - character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); - character->SetHandle(argPacket->handle); - character->SetAvatar(argPacket->avatar); - character->SetOwner(argPacket->accountIndex); - character->CorrectSprite(); - - //debug - std::cout << "Query, total: " << characterMap.size() << std::endl; -} - -void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { - //TODO: Authentication - if (argPacket->characterIndex == characterIndex) { - return; - } - - //check that this character exists - std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); - if (characterIt != characterMap.end()) { - //set the origin and motion - characterIt->second.SetOrigin(argPacket->origin); - characterIt->second.SetMotion(argPacket->motion); - characterIt->second.CorrectSprite(); - } -} - -void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { - //TODO: attack animation -} - -//------------------------- -//player movement -//------------------------- - -//TODO: add a "movement" packet type -void InWorld::SendLocalCharacterMovement() { - CharacterPacket newPacket; - newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; - - newPacket.accountIndex = accountIndex; - newPacket.characterIndex = characterIndex; - newPacket.roomIndex = roomIndex; - newPacket.origin = localCharacter->GetOrigin(); - newPacket.motion = localCharacter->GetMotion(); - - network.SendTo(Channels::SERVER, &newPacket); -} - -std::list InWorld::GenerateCollisionGrid(Entity* ptr, int tileWidth, int tileHeight) { - //prepare for collisions - BoundingBox wallBounds = {0, 0, tileWidth, tileHeight}; - std::list boxList; - - //NOTE: for loops were too dense to work with, so I've just used while loops - - //outer loop - wallBounds.x = snapToBase((double)wallBounds.w, ptr->GetOrigin().x); - while(wallBounds.x < (ptr->GetOrigin() + ptr->GetBounds()).x + ptr->GetBounds().w) { - //inner loop - wallBounds.y = snapToBase((double)wallBounds.h, ptr->GetOrigin().y); - while(wallBounds.y < (ptr->GetOrigin() + ptr->GetBounds()).y + ptr->GetBounds().h) { - //check to see if this tile is solid - if (regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) { - //push onto the box set - boxList.push_front(wallBounds); - } - - //increment - wallBounds.y += wallBounds.h; - } - - //increment - wallBounds.x += wallBounds.w; - } - - return std::move(boxList); -} \ No newline at end of file diff --git a/client/gameplay_scenes/in_world_entities.cpp b/client/gameplay_scenes/in_world_entities.cpp new file mode 100644 index 0000000..db3a2c8 --- /dev/null +++ b/client/gameplay_scenes/in_world_entities.cpp @@ -0,0 +1,196 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "in_world.hpp" + +#include "channels.hpp" + +#include +#include +#include + +//------------------------- +//entity management +//------------------------- + +//DOCS: preexisting characters will result in query responses +//DOCS: new characters will result in create messages +//DOCS: this client's character will exist in both (skipped) + +void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { + //prevent double message + if (characterMap.find(argPacket->characterIndex) != characterMap.end()) { + std::ostringstream msg; + msg << "Double character creation event; "; + msg << "Index: " << argPacket->characterIndex << "; "; + msg << "Handle: " << argPacket->handle; + throw(std::runtime_error(msg.str())); + } + + //implicity create and retrieve the entity + BaseCharacter* character = &characterMap[argPacket->characterIndex]; + + //fill the character's info + character->SetOrigin(argPacket->origin); + character->SetMotion(argPacket->motion); + character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); + character->SetHandle(argPacket->handle); + character->SetAvatar(argPacket->avatar); + character->SetOwner(argPacket->accountIndex); + character->CorrectSprite(); + + //check for this player's character + if (character->GetOwner() == accountIndex) { + localCharacter = static_cast(character); + + //focus the camera on this character + camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2); + camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2); + + //focus on this character's info + characterIndex = argPacket->characterIndex; + roomIndex = argPacket->roomIndex; + } + + //debug + std::cout << "Create, total: " << characterMap.size() << std::endl; +} + +void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { + //ignore if this character doesn't exist + std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); + if (characterIt == characterMap.end()) { + return; + } + + //check for this player's character + if ((*characterIt).second.GetOwner() == accountIndex) { + localCharacter = nullptr; + + //clear the camera + camera.marginX = 0; + camera.marginY = 0; + + //clear the room + roomIndex = -1; + } + + //remove this character + characterMap.erase(characterIt); + + //debug + std::cout << "Delete, total: " << characterMap.size() << std::endl; +} + +void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { + //prevent a double message about this player's character + if (argPacket->accountIndex == accountIndex) { + return; + } + + //ignore characters in a different room (sub-optimal) + if (argPacket->roomIndex != roomIndex) { + return; + } + + //implicitly construct the character if it doesn't exist + BaseCharacter* character = &characterMap[argPacket->characterIndex]; + + //set/update the character's info + character->SetOrigin(argPacket->origin); + character->SetMotion(argPacket->motion); + character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); + character->SetHandle(argPacket->handle); + character->SetAvatar(argPacket->avatar); + character->SetOwner(argPacket->accountIndex); + character->CorrectSprite(); + + //debug + std::cout << "Query, total: " << characterMap.size() << std::endl; +} + +void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { + //TODO: Authentication + if (argPacket->characterIndex == characterIndex) { + return; + } + + //check that this character exists + std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); + if (characterIt != characterMap.end()) { + //set the origin and motion + characterIt->second.SetOrigin(argPacket->origin); + characterIt->second.SetMotion(argPacket->motion); + characterIt->second.CorrectSprite(); + } +} + +void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { + //TODO: attack animation +} + +//------------------------- +//player movement +//------------------------- + +//TODO: add a "movement" packet type +void InWorld::SendLocalCharacterMovement() { + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; + + newPacket.accountIndex = accountIndex; + newPacket.characterIndex = characterIndex; + newPacket.roomIndex = roomIndex; + newPacket.origin = localCharacter->GetOrigin(); + newPacket.motion = localCharacter->GetMotion(); + + network.SendTo(Channels::SERVER, &newPacket); +} + +std::list InWorld::GenerateCollisionGrid(Entity* ptr, int tileWidth, int tileHeight) { + //prepare for collisions + BoundingBox wallBounds = {0, 0, tileWidth, tileHeight}; + std::list boxList; + + //NOTE: for loops were too dense to work with, so I've just used while loops + + //outer loop + wallBounds.x = snapToBase((double)wallBounds.w, ptr->GetOrigin().x); + while(wallBounds.x < (ptr->GetOrigin() + ptr->GetBounds()).x + ptr->GetBounds().w) { + //inner loop + wallBounds.y = snapToBase((double)wallBounds.h, ptr->GetOrigin().y); + while(wallBounds.y < (ptr->GetOrigin() + ptr->GetBounds()).y + ptr->GetBounds().h) { + //check to see if this tile is solid + if (regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) { + //push onto the box set + boxList.push_front(wallBounds); + } + + //increment + wallBounds.y += wallBounds.h; + } + + //increment + wallBounds.x += wallBounds.w; + } + + return std::move(boxList); +} \ No newline at end of file diff --git a/client/gameplay_scenes/in_world_networking.cpp b/client/gameplay_scenes/in_world_networking.cpp new file mode 100644 index 0000000..fc025eb --- /dev/null +++ b/client/gameplay_scenes/in_world_networking.cpp @@ -0,0 +1,248 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "in_world.hpp" + +#include "channels.hpp" +#include "terminal_error.hpp" + +#include +#include +#include + +//------------------------- +//Basic connections +//------------------------- + +void InWorld::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { + //heartbeat system + case SerialPacketType::PING: + HandlePing(static_cast(argPacket)); + break; + case SerialPacketType::PONG: + HandlePong(static_cast(argPacket)); + break; + + //game server connections + case SerialPacketType::LOGOUT_RESPONSE: + HandleLogoutResponse(static_cast(argPacket)); + break; + case SerialPacketType::DISCONNECT_RESPONSE: + HandleDisconnectResponse(static_cast(argPacket)); + break; + case SerialPacketType::DISCONNECT_FORCED: + HandleDisconnectForced(static_cast(argPacket)); + break; + + //map management + case SerialPacketType::REGION_CONTENT: + HandleRegionContent(static_cast(argPacket)); + break; + + //character management + case SerialPacketType::CHARACTER_CREATE: + HandleCharacterCreate(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_DELETE: + HandleCharacterDelete(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_EXISTS: + HandleCharacterQueryExists(static_cast(argPacket)); + break; + + //character movement + case SerialPacketType::CHARACTER_MOVEMENT: + HandleCharacterMovement(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_ATTACK: + HandleCharacterAttack(static_cast(argPacket)); + break; + + //rejection messages + case SerialPacketType::REGION_REJECTION: + case SerialPacketType::CHARACTER_REJECTION: + throw(terminal_error(static_cast(argPacket)->text)); + break; + case SerialPacketType::SHUTDOWN_REJECTION: + throw(std::runtime_error(static_cast(argPacket)->text)); + break; + + //errors + default: { + std::ostringstream msg; + msg << "Unknown SerialPacketType encountered in InWorld: " << static_cast(argPacket->type); + throw(std::runtime_error(msg.str())); + } + break; + } +} + +void InWorld::HandlePing(ServerPacket* const argPacket) { + ServerPacket newPacket; + newPacket.type = SerialPacketType::PONG; + network.SendTo(argPacket->srcAddress, &newPacket); +} + +void InWorld::HandlePong(ServerPacket* const argPacket) { + if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) { + throw(std::runtime_error("Heartbeat message received from an unknown source")); + } + attemptedBeats = 0; + lastBeat = Clock::now(); +} + +//------------------------- +//Connection control +//------------------------- + +void InWorld::SendLogoutRequest() { + ClientPacket newPacket; + + //send a logout request + newPacket.type = SerialPacketType::LOGOUT_REQUEST; + newPacket.accountIndex = accountIndex; + + network.SendTo(Channels::SERVER, &newPacket); +} + +void InWorld::SendDisconnectRequest() { + ClientPacket newPacket; + + //send a disconnect request + newPacket.type = SerialPacketType::DISCONNECT_REQUEST; + newPacket.clientIndex = clientIndex; + + network.SendTo(Channels::SERVER, &newPacket); +} + +void InWorld::SendShutdownRequest() { + ClientPacket newPacket; + + //send a shutdown request + newPacket.type = SerialPacketType::SHUTDOWN_REQUEST; + newPacket.accountIndex = accountIndex; + + network.SendTo(Channels::SERVER, &newPacket); +} + +void InWorld::HandleLogoutResponse(ClientPacket* const argPacket) { + if (localCharacter) { + characterMap.erase(characterIndex); + localCharacter = nullptr; + } + + accountIndex = -1; + characterIndex = -1; + + //reset the camera + camera.marginX = camera.marginY = 0; + + //because, why not? I guess... + SendDisconnectRequest(); +} + +void InWorld::HandleDisconnectResponse(ClientPacket* const argPacket) { + HandleLogoutResponse(argPacket);//shortcut + SetNextScene(SceneList::DISCONNECTEDSCREEN); + ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have successfully logged out"; +} + +void InWorld::HandleDisconnectForced(ClientPacket* const argPacket) { + HandleDisconnectResponse(argPacket);//shortcut + SetNextScene(SceneList::DISCONNECTEDSCREEN); + ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server"; +} + +void InWorld::CheckHeartBeat() { + //check the connection (heartbeat) + if (Clock::now() - lastBeat > std::chrono::seconds(3)) { + if (attemptedBeats > 2) { + //escape to the disconnect screen + SendDisconnectRequest(); + SetNextScene(SceneList::DISCONNECTEDSCREEN); + ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server"; + } + else { + ServerPacket newPacket; + newPacket.type = SerialPacketType::PING; + network.SendTo(Channels::SERVER, &newPacket); + + attemptedBeats++; + lastBeat = Clock::now(); + } + } +} + +//------------------------- +//map management +//------------------------- + +void InWorld::SendRegionRequest(int roomIndex, int x, int y) { + RegionPacket packet; + + //pack the region's data + packet.type = SerialPacketType::REGION_REQUEST; + packet.roomIndex = roomIndex; + packet.x = x; + packet.y = y; + + network.SendTo(Channels::SERVER, &packet); +} + +void InWorld::HandleRegionContent(RegionPacket* const argPacket) { + //replace existing regions + regionPager.UnloadIf([&](Region const& region) -> bool { + return region.GetX() == argPacket->x && region.GetY() == argPacket->y; + }); + regionPager.PushRegion(argPacket->region); + + //clean up after the serial code + delete argPacket->region; + argPacket->region = nullptr; +} + +void InWorld::UpdateMap() { + if (roomIndex == -1) { + return; + } + + //these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1) + int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH; + int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH; + + int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT; + int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT; + + //prune distant regions + regionPager.GetContainer()->remove_if([&](Region const& region) -> bool { + return region.GetX() < xStart || region.GetX() > xEnd || region.GetY() < yStart || region.GetY() > yEnd; + }); + + //request empty regions within this zone + for (int i = xStart; i <= xEnd; i += REGION_WIDTH) { + for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) { + if (!regionPager.FindRegion(i, j)) { + SendRegionRequest(roomIndex, i, j); + } + } + } +} \ No newline at end of file diff --git a/client/gameplay_scenes/in_world_scene_components.cpp b/client/gameplay_scenes/in_world_scene_components.cpp new file mode 100644 index 0000000..a7c982c --- /dev/null +++ b/client/gameplay_scenes/in_world_scene_components.cpp @@ -0,0 +1,317 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "in_world.hpp" + +#include "channels.hpp" +#include "utility.hpp" + +#include "terminal_error.hpp" +#include +#include +#include +#include +#include + +//------------------------- +//these should've come standard +//------------------------- + +bool operator==(IPaddress lhs, IPaddress rhs) { + return lhs.host == rhs.host && lhs.port == rhs.port; +} + +bool operator!=(IPaddress lhs, IPaddress rhs) { + return !(lhs == rhs); +} + +//------------------------- +//Public access members +//------------------------- + +InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): + clientIndex(*argClientIndex), + accountIndex(*argAccountIndex) +{ + //setup the utility objects + buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); + buttonImage.SetClipH(buttonImage.GetClipH()/3); + font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp"); + + //pass the utility objects + disconnectButton.SetImage(&buttonImage); + disconnectButton.SetFont(&font); + shutDownButton.SetImage(&buttonImage); + shutDownButton.SetFont(&font); + + //set the button positions + disconnectButton.SetX(50); + disconnectButton.SetY(50 + buttonImage.GetClipH() * 0); + shutDownButton.SetX(50); + shutDownButton.SetY(50 + buttonImage.GetClipH() * 1); + + //set the button texts + disconnectButton.SetText("Disconnect"); + shutDownButton.SetText("Shut Down"); + + //load the tilesheet + //TODO: add the tilesheet to the map system + //TODO: Tile size and tile sheet should be loaded elsewhere + tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32); + + //Send the character data + //TODO: login scene, prompt, etc. + CharacterPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_LOAD; + 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); + + //query the world state + memset(&newPacket, 0, MAX_PACKET_SIZE); + newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; + network.SendTo(Channels::SERVER, &newPacket); + + //set the camera's values + camera.width = GetScreen()->w; + camera.height = GetScreen()->h; + + //debug + // +} + +InWorld::~InWorld() { + //unload the local data + characterMap.clear(); + monsterMap.clear(); +} + +//------------------------- +//Frame loop +//------------------------- + +void InWorld::FrameStart() { + // +} + +void InWorld::Update() { + //create and zero the buffer + SerialPacket* packetBuffer = reinterpret_cast(new char[MAX_PACKET_SIZE]); + memset(packetBuffer, 0, MAX_PACKET_SIZE); + + try { + //suck in and process all waiting packets + while(network.Receive(packetBuffer)) { + HandlePacket(packetBuffer); + } + } + catch(terminal_error& e) { + throw(e); + } + catch(std::exception& e) { + std::cerr << "HandlePacket Error: " << e.what() << std::endl; + } + + //free the buffer + delete reinterpret_cast(packetBuffer); + + //heartbeat system + CheckHeartBeat(); + + //update all entities + for (auto& it : characterMap) { + it.second.Update(); + } + for (auto& it : monsterMap) { + it.second.Update(); + } + + //update the map + UpdateMap(); + + //skip the rest without a local character + if (!localCharacter) { + return; + } + + //get the collidable boxes + std::list boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH()); + + //process the collisions + if (localCharacter->ProcessCollisionGrid(boxList)) { + localCharacter->CorrectSprite(); + SendLocalCharacterMovement(); + } + + //update the camera + camera.x = localCharacter->GetOrigin().x - camera.marginX; + camera.y = localCharacter->GetOrigin().y - camera.marginY; +} + +void InWorld::FrameEnd() { + // +} + +void InWorld::RenderFrame() { + SDL_FillRect(GetScreen(), 0, 0); + Render(GetScreen()); + SDL_Flip(GetScreen()); + fps.Calculate(); +} + +void InWorld::Render(SDL_Surface* const screen) { + //draw the map + for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { + tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y); + } + + //draw the entities + for (auto& it : characterMap) { + //TODO: depth ordering + it.second.DrawTo(screen, camera.x, camera.y); + } + for (auto& it : monsterMap) { + //TODO: depth ordering + it.second.DrawTo(screen, camera.x, camera.y); + } + + //draw UI + disconnectButton.DrawTo(screen); + shutDownButton.DrawTo(screen); + font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0); +} + +//------------------------- +//Event handlers +//------------------------- + +void InWorld::QuitEvent() { + //two-step logout + SendDisconnectRequest(); + SetNextScene(SceneList::QUIT); +} + +void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) { + disconnectButton.MouseMotion(motion); + shutDownButton.MouseMotion(motion); +} + +void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) { + disconnectButton.MouseButtonDown(button); + shutDownButton.MouseButtonDown(button); +} + +void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) { + if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { + SendLogoutRequest(); + } + if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { + SendShutdownRequest(); + } +} + +void InWorld::KeyDown(SDL_KeyboardEvent const& key) { + //hotkeys + switch(key.keysym.sym) { + case SDLK_ESCAPE: + //TODO: the escape key should actually control menus and stuff + SendLogoutRequest(); + return; + } + + //character movement + if (!localCharacter) { + return; + } + Vector2 motion = localCharacter->GetMotion(); + switch(key.keysym.sym) { + case SDLK_w: + motion.y -= CHARACTER_WALKING_SPEED; + break; + case SDLK_a: + motion.x -= CHARACTER_WALKING_SPEED; + break; + case SDLK_s: + motion.y += CHARACTER_WALKING_SPEED; + break; + case SDLK_d: + motion.x += CHARACTER_WALKING_SPEED; + break; + default: + //DOCS: prevents wrong keys screwing with character movement + return; + } + //handle diagonals + if (motion.x != 0 && motion.y != 0) { + motion *= CHARACTER_WALKING_MOD; + } + //set the info + localCharacter->SetMotion(motion); + localCharacter->CorrectSprite(); + SendLocalCharacterMovement(); +} + +void InWorld::KeyUp(SDL_KeyboardEvent const& key) { + //character movement + if (!localCharacter) { + return; + } + Vector2 motion = localCharacter->GetMotion(); + switch(key.keysym.sym) { + case SDLK_w: + motion.y = std::min(0.0, motion.y += CHARACTER_WALKING_SPEED); + break; + case SDLK_a: + motion.x = std::min(0.0, motion.x += CHARACTER_WALKING_SPEED); + break; + case SDLK_s: + motion.y = std::max(0.0, motion.y -= CHARACTER_WALKING_SPEED); + break; + case SDLK_d: + motion.x = std::max(0.0, motion.x -= CHARACTER_WALKING_SPEED); + break; + default: + //DOCS: prevents wrong keys screwing with character movement + return; + } + //BUGFIX: reset cardinal direction speed on key release + if (motion.x > 0) { + motion.x = CHARACTER_WALKING_SPEED; + } + else if (motion.x < 0) { + motion.x = -CHARACTER_WALKING_SPEED; + } + if (motion.y > 0) { + motion.y = CHARACTER_WALKING_SPEED; + } + else if (motion.y < 0) { + motion.y = -CHARACTER_WALKING_SPEED; + } + //handle diagonals + if (motion.x != 0 && motion.y != 0) { + motion *= CHARACTER_WALKING_MOD; + } + //set the info + localCharacter->SetMotion(motion); + localCharacter->CorrectSprite(); + SendLocalCharacterMovement(); +} \ No newline at end of file From bd878e20ceceac1196fc7d68e5c232183684bd34 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 20 Jan 2015 05:02:44 +1100 Subject: [PATCH 08/21] Added monster message handlers --- client/client_utilities/ip_operators.cpp | 30 ++++++++++++++++++ client/client_utilities/ip_operators.hpp | 31 +++++++++++++++++++ client/gameplay_scenes/in_world.hpp | 7 +++++ client/gameplay_scenes/in_world_entities.cpp | 26 +++++++++++++++- .../gameplay_scenes/in_world_networking.cpp | 20 ++++++++++-- .../in_world_scene_components.cpp | 12 ------- 6 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 client/client_utilities/ip_operators.cpp create mode 100644 client/client_utilities/ip_operators.hpp diff --git a/client/client_utilities/ip_operators.cpp b/client/client_utilities/ip_operators.cpp new file mode 100644 index 0000000..fe3ba48 --- /dev/null +++ b/client/client_utilities/ip_operators.cpp @@ -0,0 +1,30 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "ip_operators.hpp" + +bool operator==(IPaddress lhs, IPaddress rhs) { + return lhs.host == rhs.host && lhs.port == rhs.port; +} + +bool operator!=(IPaddress lhs, IPaddress rhs) { + return !(lhs == rhs); +} \ No newline at end of file diff --git a/client/client_utilities/ip_operators.hpp b/client/client_utilities/ip_operators.hpp new file mode 100644 index 0000000..cdfff9e --- /dev/null +++ b/client/client_utilities/ip_operators.hpp @@ -0,0 +1,31 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef IPOPERATORS_HPP_ +#define IPOPERATORS_HPP_ + +#include "SDL/SDL_net.h" + +//these should've come standard +bool operator==(IPaddress lhs, IPaddress rhs); +bool operator!=(IPaddress lhs, IPaddress rhs); + +#endif \ No newline at end of file diff --git a/client/gameplay_scenes/in_world.hpp b/client/gameplay_scenes/in_world.hpp index d328c6d..7dfa1fc 100644 --- a/client/gameplay_scenes/in_world.hpp +++ b/client/gameplay_scenes/in_world.hpp @@ -99,6 +99,13 @@ protected: void HandleCharacterMovement(CharacterPacket* const); void HandleCharacterAttack(CharacterPacket* const); + //monster management + void HandleMonsterCreate(MonsterPacket* const); + void HandleMonsterDelete(MonsterPacket* const); + void HandleMonsterQueryExists(MonsterPacket* const); + void HandleMonsterMovement(MonsterPacket* const); + void HandleMonsterAttack(MonsterPacket* const); + //player movement void SendLocalCharacterMovement(); std::list GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight); diff --git a/client/gameplay_scenes/in_world_entities.cpp b/client/gameplay_scenes/in_world_entities.cpp index db3a2c8..7fd7155 100644 --- a/client/gameplay_scenes/in_world_entities.cpp +++ b/client/gameplay_scenes/in_world_entities.cpp @@ -28,7 +28,7 @@ #include //------------------------- -//entity management +//character management //------------------------- //DOCS: preexisting characters will result in query responses @@ -147,6 +147,30 @@ void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { //TODO: attack animation } +//------------------------- +//monster management +//------------------------- + +void InWorld::HandleMonsterCreate(MonsterPacket* const argPacket) { + //TODO +} + +void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { + //TODO +} + +void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { + //TODO +} + +void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { + //TODO +} + +void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { + //TODO +} + //------------------------- //player movement //------------------------- diff --git a/client/gameplay_scenes/in_world_networking.cpp b/client/gameplay_scenes/in_world_networking.cpp index fc025eb..db23ce1 100644 --- a/client/gameplay_scenes/in_world_networking.cpp +++ b/client/gameplay_scenes/in_world_networking.cpp @@ -22,6 +22,7 @@ #include "in_world.hpp" #include "channels.hpp" +#include "ip_operators.hpp" #include "terminal_error.hpp" #include @@ -68,8 +69,6 @@ void InWorld::HandlePacket(SerialPacket* const argPacket) { case SerialPacketType::QUERY_CHARACTER_EXISTS: HandleCharacterQueryExists(static_cast(argPacket)); break; - - //character movement case SerialPacketType::CHARACTER_MOVEMENT: HandleCharacterMovement(static_cast(argPacket)); break; @@ -77,6 +76,23 @@ void InWorld::HandlePacket(SerialPacket* const argPacket) { HandleCharacterAttack(static_cast(argPacket)); break; + //monster management + case SerialPacketType::MONSTER_CREATE: + HandleMonsterCreate(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_DELETE: + HandleMonsterDelete(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_EXISTS: + HandleMonsterQueryExists(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_MOVEMENT: + HandleMonsterMovement(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_ATTACK: + HandleMonsterAttack(static_cast(argPacket)); + break; + //rejection messages case SerialPacketType::REGION_REJECTION: case SerialPacketType::CHARACTER_REJECTION: diff --git a/client/gameplay_scenes/in_world_scene_components.cpp b/client/gameplay_scenes/in_world_scene_components.cpp index a7c982c..55ed44d 100644 --- a/client/gameplay_scenes/in_world_scene_components.cpp +++ b/client/gameplay_scenes/in_world_scene_components.cpp @@ -31,18 +31,6 @@ #include #include -//------------------------- -//these should've come standard -//------------------------- - -bool operator==(IPaddress lhs, IPaddress rhs) { - return lhs.host == rhs.host && lhs.port == rhs.port; -} - -bool operator!=(IPaddress lhs, IPaddress rhs) { - return !(lhs == rhs); -} - //------------------------- //Public access members //------------------------- From 1e8f91a871793d9f2cb678f4150000af395c68b1 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 20 Jan 2015 05:18:52 +1100 Subject: [PATCH 09/21] rename --- .../{in_world_scene_components.cpp => in_world_scene.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename client/gameplay_scenes/{in_world_scene_components.cpp => in_world_scene.cpp} (100%) diff --git a/client/gameplay_scenes/in_world_scene_components.cpp b/client/gameplay_scenes/in_world_scene.cpp similarity index 100% rename from client/gameplay_scenes/in_world_scene_components.cpp rename to client/gameplay_scenes/in_world_scene.cpp From 65f23bbd1aad9e590d33406c58d401cbd6e93609 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 20 Jan 2015 22:43:47 +1100 Subject: [PATCH 10/21] Fixed issue caused by merges --- client/gameplay_scenes/in_world_scene.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/gameplay_scenes/in_world_scene.cpp b/client/gameplay_scenes/in_world_scene.cpp index 55ed44d..284d892 100644 --- a/client/gameplay_scenes/in_world_scene.cpp +++ b/client/gameplay_scenes/in_world_scene.cpp @@ -22,7 +22,6 @@ #include "in_world.hpp" #include "channels.hpp" -#include "utility.hpp" #include "terminal_error.hpp" #include @@ -185,7 +184,9 @@ void InWorld::Render(SDL_Surface* const screen) { //draw UI disconnectButton.DrawTo(screen); shutDownButton.DrawTo(screen); - font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0); + std::ostringstream msg; + msg << fps.GetFrameRate(); + font.DrawStringTo(msg.str(), screen, 0, 0); } //------------------------- From 38f6ced6335c2a10c8d794a2409c7ba1beeaf7c5 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 21 Jan 2015 05:09:55 +1100 Subject: [PATCH 11/21] Filled out some client side monster code --- client/entities/base_monster.cpp | 23 +++++++ client/entities/base_monster.hpp | 11 ++- client/gameplay_scenes/in_world_entities.cpp | 71 +++++++++++++++++--- client/gameplay_scenes/in_world_scene.cpp | 2 + 4 files changed, 98 insertions(+), 9 deletions(-) diff --git a/client/entities/base_monster.cpp b/client/entities/base_monster.cpp index 2eaa513..788dbb1 100644 --- a/client/entities/base_monster.cpp +++ b/client/entities/base_monster.cpp @@ -21,3 +21,26 @@ */ #include "base_monster.hpp" +#include "config_utility.hpp" + +void BaseMonster::CorrectSprite() { + //TODO +} + +std::string BaseMonster::SetHandle(std::string s) { + return handle = s; +} + +std::string BaseMonster::GetHandle() const { + return handle; +} + +std::string BaseMonster::SetAvatar(std::string s) { + avatar = s; + sprite.LoadSurface(ConfigUtility::GetSingleton()["dir.sprites"] + avatar, 4, 1); + return avatar; +} + +std::string BaseMonster::GetAvatar() const { + return avatar; +} \ No newline at end of file diff --git a/client/entities/base_monster.hpp b/client/entities/base_monster.hpp index c9b7bb3..328008a 100644 --- a/client/entities/base_monster.hpp +++ b/client/entities/base_monster.hpp @@ -29,8 +29,17 @@ public: BaseMonster() = default; virtual ~BaseMonster() = default; + void CorrectSprite(); + + std::string SetHandle(std::string s); + std::string GetHandle() const; + std::string SetAvatar(std::string s); + std::string GetAvatar() const; + protected: - // + //metadata + std::string handle; + std::string avatar; }; #endif \ No newline at end of file diff --git a/client/gameplay_scenes/in_world_entities.cpp b/client/gameplay_scenes/in_world_entities.cpp index 7fd7155..c1df09a 100644 --- a/client/gameplay_scenes/in_world_entities.cpp +++ b/client/gameplay_scenes/in_world_entities.cpp @@ -51,7 +51,7 @@ void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { //fill the character's info character->SetOrigin(argPacket->origin); character->SetMotion(argPacket->motion); - character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); + character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); //TODO: send the bounds from the server character->SetHandle(argPacket->handle); character->SetAvatar(argPacket->avatar); character->SetOwner(argPacket->accountIndex); @@ -71,7 +71,7 @@ void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { } //debug - std::cout << "Create, total: " << characterMap.size() << std::endl; + std::cout << "Character Create, total: " << characterMap.size() << std::endl; } void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { @@ -97,7 +97,7 @@ void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { characterMap.erase(characterIt); //debug - std::cout << "Delete, total: " << characterMap.size() << std::endl; + std::cout << "Character Delete, total: " << characterMap.size() << std::endl; } void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { @@ -124,7 +124,7 @@ void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { character->CorrectSprite(); //debug - std::cout << "Query, total: " << characterMap.size() << std::endl; + std::cout << "Character Query, total: " << characterMap.size() << std::endl; } void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { @@ -152,15 +152,71 @@ void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { //------------------------- void InWorld::HandleMonsterCreate(MonsterPacket* const argPacket) { - //TODO + //check for logic errors + if (monsterMap.find(argPacket->monsterIndex) != monsterMap.end()) { + std::ostringstream msg; + msg << "Double monster creation event; "; + msg << "Index: " << argPacket->monsterIndex << "; "; + msg << "Handle: " << argPacket->handle; + throw(std::runtime_error(msg.str())); + } + + //ignore monsters from other rooms + if (roomIndex != argPacket->roomIndex) { + //temporary error checking + std::ostringstream msg; + msg << "Monster from the wrong room received: "; + msg << "monsterIndex: " << argPacket->monsterIndex << ", roomIndex: " << argPacket->roomIndex; + throw(std::runtime_error(msg.str())); + } + + //implicitly create the element + BaseMonster* monster = &monsterMap[argPacket->monsterIndex]; + + //fill the monster's info + monster->SetHandle(argPacket->handle); + monster->SetAvatar(argPacket->avatar); + monster->SetBounds(argPacket->bounds); + monster->SetOrigin(argPacket->origin); + monster->SetMotion(argPacket->motion); + + //debug + std::cout << "Monster Create, total: " << monsterMap.size() << std::endl; } void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { - //TODO + //ignore if this monster doesn't exist + std::map::iterator monsterIt = monsterMap.find(argPacket->monsterIndex); + if (monsterIt == monsterMap.end()) { + return; + } + + + //remove this monster + monsterMap.erase(monsterIt); + + //debug + std::cout << "Monster Delete, total: " << monsterMap.size() << std::endl; } void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { - //TODO + //ignore monsters in a different room (sub-optimal) + if (argPacket->roomIndex != roomIndex) { + return; + } + + //implicitly create the element + BaseMonster* monster = &monsterMap[argPacket->monsterIndex]; + + //fill the monster's info + monster->SetHandle(argPacket->handle); + monster->SetAvatar(argPacket->avatar); + monster->SetBounds(argPacket->bounds); + monster->SetOrigin(argPacket->origin); + monster->SetMotion(argPacket->motion); + + //debug + std::cout << "Monster Query, total: " << monsterMap.size() << std::endl; } void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { @@ -175,7 +231,6 @@ void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { //player movement //------------------------- -//TODO: add a "movement" packet type void InWorld::SendLocalCharacterMovement() { CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; diff --git a/client/gameplay_scenes/in_world_scene.cpp b/client/gameplay_scenes/in_world_scene.cpp index 284d892..d5d47ea 100644 --- a/client/gameplay_scenes/in_world_scene.cpp +++ b/client/gameplay_scenes/in_world_scene.cpp @@ -77,6 +77,8 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): memset(&newPacket, 0, MAX_PACKET_SIZE); newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; network.SendTo(Channels::SERVER, &newPacket); +// newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS; +// network.SendTo(Channels::SERVER, &newPacket); //set the camera's values camera.width = GetScreen()->w; From 0bdafe7e15a6371deb043cdaa6232719e8b74ae8 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 21 Jan 2015 05:19:02 +1100 Subject: [PATCH 12/21] minor file shuffling --- ...d_entities.cpp => in_world_characters.cpp} | 80 ------------- client/gameplay_scenes/in_world_monsters.cpp | 108 ++++++++++++++++++ server/server_logic.cpp | 32 +++--- server/server_monster_methods.cpp | 23 ++++ 4 files changed, 148 insertions(+), 95 deletions(-) rename client/gameplay_scenes/{in_world_entities.cpp => in_world_characters.cpp} (73%) create mode 100644 client/gameplay_scenes/in_world_monsters.cpp create mode 100644 server/server_monster_methods.cpp diff --git a/client/gameplay_scenes/in_world_entities.cpp b/client/gameplay_scenes/in_world_characters.cpp similarity index 73% rename from client/gameplay_scenes/in_world_entities.cpp rename to client/gameplay_scenes/in_world_characters.cpp index c1df09a..8002814 100644 --- a/client/gameplay_scenes/in_world_entities.cpp +++ b/client/gameplay_scenes/in_world_characters.cpp @@ -147,86 +147,6 @@ void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { //TODO: attack animation } -//------------------------- -//monster management -//------------------------- - -void InWorld::HandleMonsterCreate(MonsterPacket* const argPacket) { - //check for logic errors - if (monsterMap.find(argPacket->monsterIndex) != monsterMap.end()) { - std::ostringstream msg; - msg << "Double monster creation event; "; - msg << "Index: " << argPacket->monsterIndex << "; "; - msg << "Handle: " << argPacket->handle; - throw(std::runtime_error(msg.str())); - } - - //ignore monsters from other rooms - if (roomIndex != argPacket->roomIndex) { - //temporary error checking - std::ostringstream msg; - msg << "Monster from the wrong room received: "; - msg << "monsterIndex: " << argPacket->monsterIndex << ", roomIndex: " << argPacket->roomIndex; - throw(std::runtime_error(msg.str())); - } - - //implicitly create the element - BaseMonster* monster = &monsterMap[argPacket->monsterIndex]; - - //fill the monster's info - monster->SetHandle(argPacket->handle); - monster->SetAvatar(argPacket->avatar); - monster->SetBounds(argPacket->bounds); - monster->SetOrigin(argPacket->origin); - monster->SetMotion(argPacket->motion); - - //debug - std::cout << "Monster Create, total: " << monsterMap.size() << std::endl; -} - -void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { - //ignore if this monster doesn't exist - std::map::iterator monsterIt = monsterMap.find(argPacket->monsterIndex); - if (monsterIt == monsterMap.end()) { - return; - } - - - //remove this monster - monsterMap.erase(monsterIt); - - //debug - std::cout << "Monster Delete, total: " << monsterMap.size() << std::endl; -} - -void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { - //ignore monsters in a different room (sub-optimal) - if (argPacket->roomIndex != roomIndex) { - return; - } - - //implicitly create the element - BaseMonster* monster = &monsterMap[argPacket->monsterIndex]; - - //fill the monster's info - monster->SetHandle(argPacket->handle); - monster->SetAvatar(argPacket->avatar); - monster->SetBounds(argPacket->bounds); - monster->SetOrigin(argPacket->origin); - monster->SetMotion(argPacket->motion); - - //debug - std::cout << "Monster Query, total: " << monsterMap.size() << std::endl; -} - -void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { - //TODO -} - -void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { - //TODO -} - //------------------------- //player movement //------------------------- diff --git a/client/gameplay_scenes/in_world_monsters.cpp b/client/gameplay_scenes/in_world_monsters.cpp new file mode 100644 index 0000000..689b588 --- /dev/null +++ b/client/gameplay_scenes/in_world_monsters.cpp @@ -0,0 +1,108 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "in_world.hpp" + +#include "channels.hpp" + +#include +#include +#include + +//------------------------- +//monster management +//------------------------- + +void InWorld::HandleMonsterCreate(MonsterPacket* const argPacket) { + //check for logic errors + if (monsterMap.find(argPacket->monsterIndex) != monsterMap.end()) { + std::ostringstream msg; + msg << "Double monster creation event; "; + msg << "Index: " << argPacket->monsterIndex << "; "; + msg << "Handle: " << argPacket->handle; + throw(std::runtime_error(msg.str())); + } + + //ignore monsters from other rooms + if (roomIndex != argPacket->roomIndex) { + //temporary error checking + std::ostringstream msg; + msg << "Monster from the wrong room received: "; + msg << "monsterIndex: " << argPacket->monsterIndex << ", roomIndex: " << argPacket->roomIndex; + throw(std::runtime_error(msg.str())); + } + + //implicitly create the element + BaseMonster* monster = &monsterMap[argPacket->monsterIndex]; + + //fill the monster's info + monster->SetHandle(argPacket->handle); + monster->SetAvatar(argPacket->avatar); + monster->SetBounds(argPacket->bounds); + monster->SetOrigin(argPacket->origin); + monster->SetMotion(argPacket->motion); + + //debug + std::cout << "Monster Create, total: " << monsterMap.size() << std::endl; +} + +void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { + //ignore if this monster doesn't exist + std::map::iterator monsterIt = monsterMap.find(argPacket->monsterIndex); + if (monsterIt == monsterMap.end()) { + return; + } + + + //remove this monster + monsterMap.erase(monsterIt); + + //debug + std::cout << "Monster Delete, total: " << monsterMap.size() << std::endl; +} + +void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { + //ignore monsters in a different room (sub-optimal) + if (argPacket->roomIndex != roomIndex) { + return; + } + + //implicitly create the element + BaseMonster* monster = &monsterMap[argPacket->monsterIndex]; + + //fill the monster's info + monster->SetHandle(argPacket->handle); + monster->SetAvatar(argPacket->avatar); + monster->SetBounds(argPacket->bounds); + monster->SetOrigin(argPacket->origin); + monster->SetMotion(argPacket->motion); + + //debug + std::cout << "Monster Query, total: " << monsterMap.size() << std::endl; +} + +void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { + //TODO +} + +void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { + //TODO +} \ No newline at end of file diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 24192f2..23a94d1 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -261,6 +261,9 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { case SerialPacketType::QUERY_CHARACTER_EXISTS: HandleCharacterExists(static_cast(argPacket)); break; + case SerialPacketType::QUERY_MONSTER_EXISTS: +// HandleMonsterExists(static_cast(argPacket)); + break; //character management case SerialPacketType::CHARACTER_CREATE: @@ -276,16 +279,6 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { HandleCharacterUnload(static_cast(argPacket)); break; -/* case SerialPacketType::QUERY_CHARACTER_EXISTS: - // - break; - case SerialPacketType::QUERY_CHARACTER_STATS: - // - break; - case SerialPacketType::QUERY_CHARACTER_LOCATION: - // - break; -*/ //character movement case SerialPacketType::CHARACTER_MOVEMENT: HandleCharacterMovement(static_cast(argPacket)); @@ -293,12 +286,21 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { case SerialPacketType::CHARACTER_ATTACK: HandleCharacterAttack(static_cast(argPacket)); break; -/* - //enemy management - //TODO: enemy management - //TODO: text -*/ + //monster management + case SerialPacketType::MONSTER_CREATE: +// HandleMonsterCreate(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_DELETE: +// HandleMonsterDelete(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_MOVEMENT: +// HandleMonsterMovement(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_ATTACK: +// HandleMonsterAttack(static_cast(argPacket)); + break; + //handle errors default: { std::ostringstream msg; diff --git a/server/server_monster_methods.cpp b/server/server_monster_methods.cpp new file mode 100644 index 0000000..3079d7a --- /dev/null +++ b/server/server_monster_methods.cpp @@ -0,0 +1,23 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "server_application.hpp" + From a18577665a5d25316dd0c75631f1df1d6c932277 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 23 Jan 2015 03:34:53 +1100 Subject: [PATCH 13/21] Updated TODO tags --- client/entities/base_monster.cpp | 2 +- client/gameplay_scenes/in_world_monsters.cpp | 4 ++-- .../network/packet_types/character_packet.hpp | 2 +- .../network/packet_types/monster_packet.cpp | 6 ++--- server/monsters/monster_manager.cpp | 22 +++++++++---------- server/waypoints/waypoint_manager_api.cpp | 4 ++-- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/client/entities/base_monster.cpp b/client/entities/base_monster.cpp index 788dbb1..f2d6049 100644 --- a/client/entities/base_monster.cpp +++ b/client/entities/base_monster.cpp @@ -24,7 +24,7 @@ #include "config_utility.hpp" void BaseMonster::CorrectSprite() { - //TODO + //TODO: CorrectSprite } std::string BaseMonster::SetHandle(std::string s) { diff --git a/client/gameplay_scenes/in_world_monsters.cpp b/client/gameplay_scenes/in_world_monsters.cpp index 689b588..bc4bfb2 100644 --- a/client/gameplay_scenes/in_world_monsters.cpp +++ b/client/gameplay_scenes/in_world_monsters.cpp @@ -100,9 +100,9 @@ void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { } void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { - //TODO + //TODO: HandleMonsterMovement } void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { - //TODO + //TODO: HandleMonsterAttack } \ No newline at end of file diff --git a/common/network/packet_types/character_packet.hpp b/common/network/packet_types/character_packet.hpp index 9b7dfde..bd3d57e 100644 --- a/common/network/packet_types/character_packet.hpp +++ b/common/network/packet_types/character_packet.hpp @@ -41,7 +41,7 @@ struct CharacterPacket : SerialPacketBase { Vector2 origin; Vector2 motion; - //gameplay components: equipment, items, buffs, debuffs... + //TODO: gameplay components: equipment, items, buffs, debuffs... }; void serializeCharacter(void* buffer, CharacterPacket* packet); diff --git a/common/network/packet_types/monster_packet.cpp b/common/network/packet_types/monster_packet.cpp index 5304550..2b0c933 100644 --- a/common/network/packet_types/monster_packet.cpp +++ b/common/network/packet_types/monster_packet.cpp @@ -45,8 +45,7 @@ void serializeMonster(void* buffer, MonsterPacket* packet) { serialCopy(&buffer, &packet->motion.x, sizeof(double)); serialCopy(&buffer, &packet->motion.y, sizeof(double)); - //attack data - //TODO + //TODO: attack data } void deserializeMonster(void* buffer, MonsterPacket* packet) { @@ -71,6 +70,5 @@ void deserializeMonster(void* buffer, MonsterPacket* packet) { deserialCopy(&buffer, &packet->motion.x, sizeof(double)); deserialCopy(&buffer, &packet->motion.y, sizeof(double)); - //attack data - //TODO + //TODO: attack data } diff --git a/server/monsters/monster_manager.cpp b/server/monsters/monster_manager.cpp index 5717e45..d1f2d45 100644 --- a/server/monsters/monster_manager.cpp +++ b/server/monsters/monster_manager.cpp @@ -30,45 +30,45 @@ MonsterManager::~MonsterManager() { } int MonsterManager::Create(std::string) { - //TODO + //TODO: Create } void MonsterManager::Unload(int uid) { - //TODO + //TODO: Unload } void MonsterManager::UnloadAll() { - //TODO + //TODO: UnloadAll } void MonsterManager::UnloadIf(std::function)> fn) { - //TODO + //TODO: UnloadIf } MonsterData* MonsterManager::Get(int uid) { - //TODO + //TODO: Get } int MonsterManager::GetLoadedCount() { - //TODO + //TODO: GetLoadedCount } std::map* MonsterManager::GetContainer() { - //TODO + //TODO: GetContainer } lua_State* MonsterManager::SetLuaState(lua_State* L) { - //TODO + //TODO: SetLuaState } lua_State* MonsterManager::GetLuaState() { - //TODO + //TODO: GetLuaState } sqlite3* MonsterManager::SetDatabase(sqlite3* db) { - //TODO + //TODO: SetDatabase } sqlite3* MonsterManager::GetDatabase() { - //TODO + //TODO: GetDatabase } diff --git a/server/waypoints/waypoint_manager_api.cpp b/server/waypoints/waypoint_manager_api.cpp index 447c666..d8ce4fa 100644 --- a/server/waypoints/waypoint_manager_api.cpp +++ b/server/waypoints/waypoint_manager_api.cpp @@ -27,12 +27,12 @@ static int create(lua_State* L) { WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); - //TODO + //TODO: create } static int unload(lua_State* L) { WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); - //TODO + //TODO: create } static int getWaypoint(lua_State* L) { From 5583ba432389bad0df2dc8fbbca71541ce9086bd Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 4 Feb 2015 16:52:22 +1100 Subject: [PATCH 14/21] Updated TODO comments --- client/gameplay_scenes/in_world_scene.cpp | 2 +- rsc/scripts/setup_server.sql | 2 +- todo.txt | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/gameplay_scenes/in_world_scene.cpp b/client/gameplay_scenes/in_world_scene.cpp index d5d47ea..46db8e0 100644 --- a/client/gameplay_scenes/in_world_scene.cpp +++ b/client/gameplay_scenes/in_world_scene.cpp @@ -161,7 +161,7 @@ void InWorld::FrameEnd() { } void InWorld::RenderFrame() { - SDL_FillRect(GetScreen(), 0, 0); +// SDL_FillRect(GetScreen(), 0, 0); Render(GetScreen()); SDL_Flip(GetScreen()); fps.Calculate(); diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index e7e9c63..5109ae8 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -2,7 +2,7 @@ CREATE TABLE IF NOT EXISTS Accounts ( uid INTEGER PRIMARY KEY AUTOINCREMENT, - username varchar(100) UNIQUE, + username varchar(100) UNIQUE, --TODO: Swap username for email address --TODO: server-client security -- passhash varchar(100), diff --git a/todo.txt b/todo.txt index 0ff79a3..c4582aa 100644 --- a/todo.txt +++ b/todo.txt @@ -7,6 +7,7 @@ TODO: Account passwords (list) * ... * salts & hashes +TODO: Make sure login errors are sent to the client TODO: Split config.cfg in two, one for the server and the client TODO: Add the "home" parameter to the server's config file TODO: Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. From 95e3ce9a692087a10bc73610966dee831cb93655 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 5 Feb 2015 22:23:59 +1100 Subject: [PATCH 15/21] Re-added the network version --- client/gameplay_scenes/in_world_monsters.cpp | 10 ++- common/network/serial_packet.hpp | 2 +- common/network/serial_packet_type.hpp | 82 ++++++++++---------- 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/client/gameplay_scenes/in_world_monsters.cpp b/client/gameplay_scenes/in_world_monsters.cpp index bc4bfb2..2e4179e 100644 --- a/client/gameplay_scenes/in_world_monsters.cpp +++ b/client/gameplay_scenes/in_world_monsters.cpp @@ -71,7 +71,6 @@ void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { return; } - //remove this monster monsterMap.erase(monsterIt); @@ -100,7 +99,14 @@ void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { } void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { - //TODO: HandleMonsterMovement + //ignore if this monster doesn't exist + std::map::iterator monsterIt = monsterMap.find(argPacket->monsterIndex); + if (monsterIt == monsterMap.end()) { + return; + } + + monsterIt.SetOrigin(argPacket->origin); + monsterIt.SetOrigin(argPacket->motion); } void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index fad3dce..0a73f43 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -34,7 +34,7 @@ typedef SerialPacketBase SerialPacket; //DOCS: NETWORK_VERSION is used to discern compatible servers and clients -constexpr int NETWORK_VERSION = -1; +constexpr int NETWORK_VERSION = 20150205; union MaxPacket { CharacterPacket a; diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index bfd808c..a27e0ea 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -30,7 +30,7 @@ //TODO: This needs to be smoothed out enum class SerialPacketType { //default: there is something wrong - NONE, + NONE = 0, //------------------------- //ServerPacket @@ -38,12 +38,12 @@ enum class SerialPacketType { //------------------------- //heartbeat - PING, - PONG, + PING = 1, + PONG = 2, //Used for finding available servers - BROADCAST_REQUEST, - BROADCAST_RESPONSE, + BROADCAST_REQUEST = 3, + BROADCAST_RESPONSE = 4, //------------------------- //ClientPacket @@ -51,24 +51,24 @@ enum class SerialPacketType { //------------------------- //Connecting to a server as a client - JOIN_REQUEST, - JOIN_RESPONSE, + JOIN_REQUEST = 5, + JOIN_RESPONSE = 6, //disconnect from the server - DISCONNECT_REQUEST, - DISCONNECT_RESPONSE, - DISCONNECT_FORCED, + DISCONNECT_REQUEST = 7, + DISCONNECT_RESPONSE = 8, + DISCONNECT_FORCED = 9, //load the account - LOGIN_REQUEST, - LOGIN_RESPONSE, + LOGIN_REQUEST = 10, + LOGIN_RESPONSE = 11, //unload the account - LOGOUT_REQUEST, - LOGOUT_RESPONSE, + LOGOUT_REQUEST = 12, + LOGOUT_RESPONSE = 13, //shut down the server - SHUTDOWN_REQUEST, + SHUTDOWN_REQUEST = 14, //------------------------- //RegionPacket @@ -76,8 +76,8 @@ enum class SerialPacketType { //------------------------- //map data - REGION_REQUEST, //NOTE: technically a query - REGION_CONTENT, + REGION_REQUEST = 15, //NOTE: technically a query + REGION_CONTENT = 16, //------------------------- //CharacterPacket @@ -89,19 +89,19 @@ enum class SerialPacketType { //------------------------- //character management - CHARACTER_CREATE, - CHARACTER_DELETE, - CHARACTER_LOAD, - CHARACTER_UNLOAD, + CHARACTER_CREATE = 17, + CHARACTER_DELETE = 18, + CHARACTER_LOAD = 19, + CHARACTER_UNLOAD = 20, //find out info from the server - QUERY_CHARACTER_EXISTS, - QUERY_CHARACTER_STATS, - QUERY_CHARACTER_LOCATION, + QUERY_CHARACTER_EXISTS = 21, + QUERY_CHARACTER_STATS = 22, + QUERY_CHARACTER_LOCATION = 23, //set the info in the server - CHARACTER_MOVEMENT, - CHARACTER_ATTACK, + CHARACTER_MOVEMENT = 24, + CHARACTER_ATTACK = 25, //admin control // ADMIN_SET_CHARACTER_ORIGIN, @@ -114,15 +114,15 @@ enum class SerialPacketType { // TODO: attack data //------------------------- - MONSTER_CREATE, - MONSTER_DELETE, + MONSTER_CREATE = 26, + MONSTER_DELETE = 27, - QUERY_MONSTER_EXISTS, //a list of monsters in a room - QUERY_MONSTER_STATS, //statistics of a specific monster type or instance - QUERY_MONSTER_LOCATION, //umm... + QUERY_MONSTER_EXISTS = 28, //a list of monsters in a room + QUERY_MONSTER_STATS = 29, //statistics of a specific monster type or instance + QUERY_MONSTER_LOCATION = 30, //umm... - MONSTER_MOVEMENT, //monster movement - MONSTER_ATTACK, + MONSTER_MOVEMENT = 31, //monster movement + MONSTER_ATTACK = 32, //------------------------- //TextPacket @@ -130,21 +130,21 @@ enum class SerialPacketType { //------------------------- //general speech - TEXT_BROADCAST, + TEXT_BROADCAST = 33, //rejection/error messages - JOIN_REJECTION, - LOGIN_REJECTION, - REGION_REJECTION, - CHARACTER_REJECTION, - MONSTER_REJECTION, - SHUTDOWN_REJECTION, + JOIN_REJECTION = 34, + LOGIN_REJECTION = 35, + REGION_REJECTION = 36, + CHARACTER_REJECTION = 37, + MONSTER_REJECTION = 38, + SHUTDOWN_REJECTION = 39, //------------------------- //not used //------------------------- - LAST + LAST = 40 }; #endif \ No newline at end of file From bad6cc2fabfff41fdc3314a6d9dcaacc4bffd45d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 5 Feb 2015 23:06:22 +1100 Subject: [PATCH 16/21] Moved ip_operators.*pp to common/utilities --- client/gameplay_scenes/in_world_monsters.cpp | 4 ++-- .../utilities}/ip_operators.cpp | 0 .../utilities}/ip_operators.hpp | 0 server/server_application.hpp | 5 +---- server/server_methods.cpp | 12 ------------ 5 files changed, 3 insertions(+), 18 deletions(-) rename {client/client_utilities => common/utilities}/ip_operators.cpp (100%) rename {client/client_utilities => common/utilities}/ip_operators.hpp (100%) diff --git a/client/gameplay_scenes/in_world_monsters.cpp b/client/gameplay_scenes/in_world_monsters.cpp index 2e4179e..d0e3b2c 100644 --- a/client/gameplay_scenes/in_world_monsters.cpp +++ b/client/gameplay_scenes/in_world_monsters.cpp @@ -105,8 +105,8 @@ void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { return; } - monsterIt.SetOrigin(argPacket->origin); - monsterIt.SetOrigin(argPacket->motion); + monsterIt->second.SetOrigin(argPacket->origin); + monsterIt->second.SetOrigin(argPacket->motion); } void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { diff --git a/client/client_utilities/ip_operators.cpp b/common/utilities/ip_operators.cpp similarity index 100% rename from client/client_utilities/ip_operators.cpp rename to common/utilities/ip_operators.cpp diff --git a/client/client_utilities/ip_operators.hpp b/common/utilities/ip_operators.hpp similarity index 100% rename from client/client_utilities/ip_operators.hpp rename to common/utilities/ip_operators.hpp diff --git a/server/server_application.hpp b/server/server_application.hpp index 05a75a6..e9a0a41 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -34,6 +34,7 @@ #include "udp_network_utility.hpp" //common utilities +#include "ip_operators.hpp" #include "serial_packet.hpp" #include "singleton.hpp" @@ -47,10 +48,6 @@ #include #include -//global utility functions -bool operator==(IPaddress lhs, IPaddress rhs); -bool operator!=(IPaddress lhs, IPaddress rhs); - //The main application class class ServerApplication: public Singleton { public: diff --git a/server/server_methods.cpp b/server/server_methods.cpp index 1d50643..2bd79c0 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -25,18 +25,6 @@ #include #include -//------------------------- -//these should've come standard -//------------------------- - -bool operator==(IPaddress lhs, IPaddress rhs) { - return lhs.host == rhs.host && lhs.port == rhs.port; -} - -bool operator!=(IPaddress lhs, IPaddress rhs) { - return !(lhs == rhs); -} - //------------------------- //server commands //------------------------- From ca2d4c9217233502c4beb39d5c5a7cc89e677dcb Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 13 Feb 2015 02:05:10 +1100 Subject: [PATCH 17/21] Expanded network protocol, read more Not really doing much, just busywork with the server's handlers. I've tweaked the TODO tags as well. --- client/base_scene.cpp | 2 +- client/base_scene.hpp | 2 +- client/client_application.cpp | 1 - client/entities/base_monster.cpp | 2 +- client/gameplay_scenes/in_world.hpp | 2 +- .../gameplay_scenes/in_world_characters.cpp | 6 +- client/gameplay_scenes/in_world_monsters.cpp | 2 +- client/gameplay_scenes/in_world_scene.cpp | 9 +- client/menu_scenes/lobby_menu.cpp | 10 +- client/menu_scenes/main_menu.cpp | 5 +- client/menu_scenes/options_menu.hpp | 2 +- .../network/packet_types/character_packet.hpp | 3 - common/network/packet_types/client_packet.hpp | 1 + .../network/packet_types/monster_packet.cpp | 4 - .../network/packet_types/monster_packet.hpp | 2 - common/network/serial_packet.hpp | 2 +- common/network/serial_packet_type.hpp | 92 +++++++++---------- common/network/serial_utility.cpp | 12 ++- common/network/udp_network_utility.cpp | 1 - rsc/scripts/map_saver.lua | 2 +- rsc/scripts/setup_server.sql | 8 +- server/accounts/account_data.hpp | 2 +- server/monsters/monster_manager.cpp | 22 ++--- server/rooms/room_api.cpp | 1 - server/rooms/room_manager_api.cpp | 2 +- server/server_application.hpp | 57 +++++++----- server/server_character_methods.cpp | 10 +- server/server_connections.cpp | 2 +- server/server_data.cpp | 4 +- server/server_logic.cpp | 77 +++++++++------- server/waypoints/waypoint_manager_api.cpp | 2 - todo.txt | 31 ++++--- 32 files changed, 196 insertions(+), 184 deletions(-) diff --git a/client/base_scene.cpp b/client/base_scene.cpp index ba62b4c..816f80b 100644 --- a/client/base_scene.cpp +++ b/client/base_scene.cpp @@ -127,7 +127,7 @@ void BaseScene::HandleEvents() { break; #ifdef USE_EVENT_JOYSTICK - //TODO: joystick/gamepad support + //EMPTY #endif #ifdef USE_EVENT_UNKNOWN diff --git a/client/base_scene.hpp b/client/base_scene.hpp index 453ab75..aae6161 100644 --- a/client/base_scene.hpp +++ b/client/base_scene.hpp @@ -59,7 +59,7 @@ protected: virtual void KeyUp(SDL_KeyboardEvent const&) {} #ifdef USE_EVENT_JOYSTICK - //TODO: joystick/gamepad support + //EMPTY #endif #ifdef USE_EVENT_UNKNOWN diff --git a/client/client_application.cpp b/client/client_application.cpp index 70957fe..21ad65e 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -83,7 +83,6 @@ void ClientApplication::Init(int argc, char* argv[]) { //debug output //------------------------- - //TODO: enable/disable these with a switch #define DEBUG_OUTPUT_VAR(x) std::cout << "\t" << #x << ": " << x << std::endl; std::cout << "Internal sizes:" << std::endl; diff --git a/client/entities/base_monster.cpp b/client/entities/base_monster.cpp index f2d6049..2d979e0 100644 --- a/client/entities/base_monster.cpp +++ b/client/entities/base_monster.cpp @@ -24,7 +24,7 @@ #include "config_utility.hpp" void BaseMonster::CorrectSprite() { - //TODO: CorrectSprite + //TODO: (1) CorrectSprite } std::string BaseMonster::SetHandle(std::string s) { diff --git a/client/gameplay_scenes/in_world.hpp b/client/gameplay_scenes/in_world.hpp index 7dfa1fc..bbf4705 100644 --- a/client/gameplay_scenes/in_world.hpp +++ b/client/gameplay_scenes/in_world.hpp @@ -142,7 +142,7 @@ protected: LocalCharacter* localCharacter = nullptr; //heartbeat - //TODO: Heartbeat needs it's own utility + //TODO: (9) Heartbeat needs it's own utility typedef std::chrono::steady_clock Clock; Clock::time_point lastBeat = Clock::now(); int attemptedBeats = 0; diff --git a/client/gameplay_scenes/in_world_characters.cpp b/client/gameplay_scenes/in_world_characters.cpp index 8002814..328cfd7 100644 --- a/client/gameplay_scenes/in_world_characters.cpp +++ b/client/gameplay_scenes/in_world_characters.cpp @@ -51,7 +51,7 @@ void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { //fill the character's info character->SetOrigin(argPacket->origin); character->SetMotion(argPacket->motion); - character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); //TODO: send the bounds from the server + character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); //TODO: (1) send the bounds from the server character->SetHandle(argPacket->handle); character->SetAvatar(argPacket->avatar); character->SetOwner(argPacket->accountIndex); @@ -128,7 +128,7 @@ void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { } void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { - //TODO: Authentication + //TODO: (1) Authentication if (argPacket->characterIndex == characterIndex) { return; } @@ -144,7 +144,7 @@ void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { } void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { - //TODO: attack animation + //TODO: (1) attack animation } //------------------------- diff --git a/client/gameplay_scenes/in_world_monsters.cpp b/client/gameplay_scenes/in_world_monsters.cpp index d0e3b2c..c9f3a45 100644 --- a/client/gameplay_scenes/in_world_monsters.cpp +++ b/client/gameplay_scenes/in_world_monsters.cpp @@ -110,5 +110,5 @@ void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { } void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { - //TODO: HandleMonsterAttack + //TODO: (1) HandleMonsterAttack } \ No newline at end of file diff --git a/client/gameplay_scenes/in_world_scene.cpp b/client/gameplay_scenes/in_world_scene.cpp index 46db8e0..44004ea 100644 --- a/client/gameplay_scenes/in_world_scene.cpp +++ b/client/gameplay_scenes/in_world_scene.cpp @@ -60,12 +60,10 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): shutDownButton.SetText("Shut Down"); //load the tilesheet - //TODO: add the tilesheet to the map system - //TODO: Tile size and tile sheet should be loaded elsewhere + //TODO: (9) Tile size and tile sheet should be loaded elsewhere tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32); //Send the character data - //TODO: login scene, prompt, etc. CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_LOAD; strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE); @@ -175,11 +173,10 @@ void InWorld::Render(SDL_Surface* const screen) { //draw the entities for (auto& it : characterMap) { - //TODO: depth ordering + //TODO: (1) depth ordering it.second.DrawTo(screen, camera.x, camera.y); } for (auto& it : monsterMap) { - //TODO: depth ordering it.second.DrawTo(screen, camera.x, camera.y); } @@ -224,7 +221,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { //hotkeys switch(key.keysym.sym) { case SDLK_ESCAPE: - //TODO: the escape key should actually control menus and stuff + //TODO: (9) the escape key should actually control menus and stuff SendLogoutRequest(); return; } diff --git a/client/menu_scenes/lobby_menu.cpp b/client/menu_scenes/lobby_menu.cpp index befc6f5..95704a0 100644 --- a/client/menu_scenes/lobby_menu.cpp +++ b/client/menu_scenes/lobby_menu.cpp @@ -100,14 +100,14 @@ void LobbyMenu::FrameEnd() { } void LobbyMenu::Render(SDL_Surface* const screen) { - //TODO: I need a proper UI system for the entire client and the editor + //TODO: (9) I need a proper UI system for the entire client and the editor //UI search.DrawTo(screen); join.DrawTo(screen); back.DrawTo(screen); - //TODO: draw headers for the server list + //TODO: (9) draw headers for the server list for (int i = 0; i < serverInfo.size(); i++) { //draw the selected server's highlight if (selection == &serverInfo[i]) { @@ -131,8 +131,6 @@ void LobbyMenu::Render(SDL_Surface* const screen) { if (!serverInfo[i].compatible) { font.DrawStringTo("?", screen, listBox.x - font.GetCharW(), listBox.y + i*listBox.h); } - - //TODO: ping/delay? } } @@ -254,11 +252,11 @@ void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) { } void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) { - //TODO: Better output for join rejection + //TODO: (9) Better output for join rejection } void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) { - //TODO: Better output for login rejection + //TODO: (9) Better output for login rejection } //------------------------- diff --git a/client/menu_scenes/main_menu.cpp b/client/menu_scenes/main_menu.cpp index 064b485..cd62757 100644 --- a/client/menu_scenes/main_menu.cpp +++ b/client/menu_scenes/main_menu.cpp @@ -88,8 +88,7 @@ void MainMenu::Render(SDL_Surface* const screen) { //text font.DrawStringTo("Thanks for playing!", screen, 50, screen->h - 50 - image.GetClipH() * 2); font.DrawStringTo("You can get the latest version at: ", screen, 50, screen->h - 50 - image.GetClipH() * 1); - font.DrawStringTo("https://github.com/Ratstail91/Tortuga", screen, 50, screen->h - 50 - image.GetClipH() * 0); - //TODO: replace this with a website address + font.DrawStringTo("krgamestudios.com", screen, 50, screen->h - 50 - image.GetClipH() * 0); } //------------------------- @@ -109,7 +108,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { } void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { - //TODO: Buttons should only register as "selected" when the left button is used + //TODO: (9) Buttons should only register as "selected" when the left button is used if (startButton.MouseButtonUp(button) == Button::State::HOVER) { SetNextScene(SceneList::LOBBYMENU); } diff --git a/client/menu_scenes/options_menu.hpp b/client/menu_scenes/options_menu.hpp index bb15569..a828627 100644 --- a/client/menu_scenes/options_menu.hpp +++ b/client/menu_scenes/options_menu.hpp @@ -28,7 +28,7 @@ #include "raster_font.hpp" #include "button.hpp" -//TODO: The options screen needs to be USED +//NOTE: The options screen needs to be USED class OptionsMenu : public BaseScene { public: //Public access members diff --git a/common/network/packet_types/character_packet.hpp b/common/network/packet_types/character_packet.hpp index bd3d57e..c7e1040 100644 --- a/common/network/packet_types/character_packet.hpp +++ b/common/network/packet_types/character_packet.hpp @@ -34,14 +34,11 @@ struct CharacterPacket : SerialPacketBase { //the owner int accountIndex; - //TODO: Authentication token? //location int roomIndex; Vector2 origin; Vector2 motion; - - //TODO: gameplay components: equipment, items, buffs, debuffs... }; void serializeCharacter(void* buffer, CharacterPacket* packet); diff --git a/common/network/packet_types/client_packet.hpp b/common/network/packet_types/client_packet.hpp index 32efb06..2d684b1 100644 --- a/common/network/packet_types/client_packet.hpp +++ b/common/network/packet_types/client_packet.hpp @@ -28,6 +28,7 @@ struct ClientPacket : SerialPacketBase { int clientIndex; int accountIndex; char username[PACKET_STRING_SIZE]; + //TODO: (9) password, auth token }; void serializeClient(void* buffer, ClientPacket* packet); diff --git a/common/network/packet_types/monster_packet.cpp b/common/network/packet_types/monster_packet.cpp index 2b0c933..c365207 100644 --- a/common/network/packet_types/monster_packet.cpp +++ b/common/network/packet_types/monster_packet.cpp @@ -44,8 +44,6 @@ void serializeMonster(void* buffer, MonsterPacket* packet) { serialCopy(&buffer, &packet->origin.y, sizeof(double)); serialCopy(&buffer, &packet->motion.x, sizeof(double)); serialCopy(&buffer, &packet->motion.y, sizeof(double)); - - //TODO: attack data } void deserializeMonster(void* buffer, MonsterPacket* packet) { @@ -69,6 +67,4 @@ void deserializeMonster(void* buffer, MonsterPacket* packet) { deserialCopy(&buffer, &packet->origin.y, sizeof(double)); deserialCopy(&buffer, &packet->motion.x, sizeof(double)); deserialCopy(&buffer, &packet->motion.y, sizeof(double)); - - //TODO: attack data } diff --git a/common/network/packet_types/monster_packet.hpp b/common/network/packet_types/monster_packet.hpp index 97ebd38..1dfae0c 100644 --- a/common/network/packet_types/monster_packet.hpp +++ b/common/network/packet_types/monster_packet.hpp @@ -38,8 +38,6 @@ struct MonsterPacket : SerialPacketBase { int roomIndex; Vector2 origin; Vector2 motion; - - //TODO: attack data }; void serializeMonster(void* buffer, MonsterPacket* packet); diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 0a73f43..0c07cae 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -34,7 +34,7 @@ typedef SerialPacketBase SerialPacket; //DOCS: NETWORK_VERSION is used to discern compatible servers and clients -constexpr int NETWORK_VERSION = 20150205; +constexpr int NETWORK_VERSION = 20150213; union MaxPacket { CharacterPacket a; diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index a27e0ea..d8b76e7 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -27,10 +27,9 @@ * valid data, but it will still be carried in that packet's format. */ -//TODO: This needs to be smoothed out enum class SerialPacketType { //default: there is something wrong - NONE = 0, + NONE, //------------------------- //ServerPacket @@ -38,12 +37,12 @@ enum class SerialPacketType { //------------------------- //heartbeat - PING = 1, - PONG = 2, + PING, + PONG, //Used for finding available servers - BROADCAST_REQUEST = 3, - BROADCAST_RESPONSE = 4, + BROADCAST_REQUEST, + BROADCAST_RESPONSE, //------------------------- //ClientPacket @@ -51,24 +50,24 @@ enum class SerialPacketType { //------------------------- //Connecting to a server as a client - JOIN_REQUEST = 5, - JOIN_RESPONSE = 6, + JOIN_REQUEST, + JOIN_RESPONSE, //disconnect from the server - DISCONNECT_REQUEST = 7, - DISCONNECT_RESPONSE = 8, - DISCONNECT_FORCED = 9, + DISCONNECT_REQUEST, + DISCONNECT_RESPONSE, + ADMIN_DISCONNECT_FORCED, //load the account - LOGIN_REQUEST = 10, - LOGIN_RESPONSE = 11, + LOGIN_REQUEST, + LOGIN_RESPONSE, //unload the account - LOGOUT_REQUEST = 12, - LOGOUT_RESPONSE = 13, + LOGOUT_REQUEST, + LOGOUT_RESPONSE, //shut down the server - SHUTDOWN_REQUEST = 14, + ADMIN_SHUTDOWN_REQUEST, //------------------------- //RegionPacket @@ -76,32 +75,32 @@ enum class SerialPacketType { //------------------------- //map data - REGION_REQUEST = 15, //NOTE: technically a query - REGION_CONTENT = 16, + REGION_REQUEST, + REGION_CONTENT, //------------------------- //CharacterPacket // character index, // handle, avatar, // account index (owner), - // room index, origin, motion, - // statistics + // room index, origin, motion //------------------------- //character management - CHARACTER_CREATE = 17, - CHARACTER_DELETE = 18, - CHARACTER_LOAD = 19, - CHARACTER_UNLOAD = 20, + CHARACTER_CREATE, + CHARACTER_DELETE, + CHARACTER_LOAD, + CHARACTER_UNLOAD, //find out info from the server - QUERY_CHARACTER_EXISTS = 21, - QUERY_CHARACTER_STATS = 22, - QUERY_CHARACTER_LOCATION = 23, + QUERY_CHARACTER_EXISTS, + QUERY_CHARACTER_STATS, + QUERY_CHARACTER_LOCATION, //set the info in the server - CHARACTER_MOVEMENT = 24, - CHARACTER_ATTACK = 25, + CHARACTER_MOVEMENT, + CHARACTER_ATTACK, + CHARACTER_DAMAGE, //admin control // ADMIN_SET_CHARACTER_ORIGIN, @@ -109,20 +108,21 @@ enum class SerialPacketType { //------------------------- //MonsterPacket // monster index, - // handle, avatar, hitbox + // handle, avatar + // bounds // room index, origin, motion - // TODO: attack data //------------------------- - MONSTER_CREATE = 26, - MONSTER_DELETE = 27, + MONSTER_CREATE, + MONSTER_DELETE, - QUERY_MONSTER_EXISTS = 28, //a list of monsters in a room - QUERY_MONSTER_STATS = 29, //statistics of a specific monster type or instance - QUERY_MONSTER_LOCATION = 30, //umm... + QUERY_MONSTER_EXISTS, + QUERY_MONSTER_STATS, + QUERY_MONSTER_LOCATION, - MONSTER_MOVEMENT = 31, //monster movement - MONSTER_ATTACK = 32, + MONSTER_MOVEMENT, + MONSTER_ATTACK, + MONSTER_DAMAGE, //------------------------- //TextPacket @@ -130,21 +130,21 @@ enum class SerialPacketType { //------------------------- //general speech - TEXT_BROADCAST = 33, + TEXT_BROADCAST, //rejection/error messages - JOIN_REJECTION = 34, - LOGIN_REJECTION = 35, - REGION_REJECTION = 36, - CHARACTER_REJECTION = 37, - MONSTER_REJECTION = 38, - SHUTDOWN_REJECTION = 39, + JOIN_REJECTION, + LOGIN_REJECTION, + REGION_REJECTION, + CHARACTER_REJECTION, + MONSTER_REJECTION, + SHUTDOWN_REJECTION, //------------------------- //not used //------------------------- - LAST = 40 + LAST }; #endif \ No newline at end of file diff --git a/common/network/serial_utility.cpp b/common/network/serial_utility.cpp index e258a9e..a584ad0 100644 --- a/common/network/serial_utility.cpp +++ b/common/network/serial_utility.cpp @@ -57,12 +57,12 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::JOIN_RESPONSE: case SerialPacketType::DISCONNECT_REQUEST: case SerialPacketType::DISCONNECT_RESPONSE: - case SerialPacketType::DISCONNECT_FORCED: + case SerialPacketType::ADMIN_DISCONNECT_FORCED: case SerialPacketType::LOGIN_REQUEST: case SerialPacketType::LOGIN_RESPONSE: case SerialPacketType::LOGOUT_REQUEST: case SerialPacketType::LOGOUT_RESPONSE: - case SerialPacketType::SHUTDOWN_REQUEST: + case SerialPacketType::ADMIN_SHUTDOWN_REQUEST: serializeClient(buffer, static_cast(packet)); break; case SerialPacketType::REGION_REQUEST: @@ -78,6 +78,7 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::QUERY_CHARACTER_LOCATION: case SerialPacketType::CHARACTER_MOVEMENT: case SerialPacketType::CHARACTER_ATTACK: + case SerialPacketType::CHARACTER_DAMAGE: serializeCharacter(buffer, static_cast(packet)); break; case SerialPacketType::MONSTER_CREATE: @@ -87,6 +88,7 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::QUERY_MONSTER_LOCATION: case SerialPacketType::MONSTER_MOVEMENT: case SerialPacketType::MONSTER_ATTACK: + case SerialPacketType::MONSTER_DAMAGE: serializeMonster(buffer, static_cast(packet)); break; case SerialPacketType::TEXT_BROADCAST: @@ -117,12 +119,12 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::JOIN_RESPONSE: case SerialPacketType::DISCONNECT_REQUEST: case SerialPacketType::DISCONNECT_RESPONSE: - case SerialPacketType::DISCONNECT_FORCED: + case SerialPacketType::ADMIN_DISCONNECT_FORCED: case SerialPacketType::LOGIN_REQUEST: case SerialPacketType::LOGIN_RESPONSE: case SerialPacketType::LOGOUT_REQUEST: case SerialPacketType::LOGOUT_RESPONSE: - case SerialPacketType::SHUTDOWN_REQUEST: + case SerialPacketType::ADMIN_SHUTDOWN_REQUEST: deserializeClient(buffer, static_cast(packet)); break; case SerialPacketType::REGION_REQUEST: @@ -138,6 +140,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::QUERY_CHARACTER_LOCATION: case SerialPacketType::CHARACTER_MOVEMENT: case SerialPacketType::CHARACTER_ATTACK: + case SerialPacketType::CHARACTER_DAMAGE: deserializeCharacter(buffer, static_cast(packet)); break; case SerialPacketType::MONSTER_CREATE: @@ -147,6 +150,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::QUERY_MONSTER_LOCATION: case SerialPacketType::MONSTER_MOVEMENT: case SerialPacketType::MONSTER_ATTACK: + case SerialPacketType::MONSTER_DAMAGE: deserializeMonster(buffer, static_cast(packet)); break; case SerialPacketType::TEXT_BROADCAST: diff --git a/common/network/udp_network_utility.cpp b/common/network/udp_network_utility.cpp index 4dfb044..ec8733f 100644 --- a/common/network/udp_network_utility.cpp +++ b/common/network/udp_network_utility.cpp @@ -140,7 +140,6 @@ int UDPNetworkUtility::SendToAllChannels(void* data, int len) { return sent; } -//TODO: put a void* and int* parameter list here int UDPNetworkUtility::Receive() { memset(packet->data, 0, packet->maxlen); int ret = SDLNet_UDP_Recv(socket, packet); diff --git a/rsc/scripts/map_saver.lua b/rsc/scripts/map_saver.lua index b9b77ea..0715807 100644 --- a/rsc/scripts/map_saver.lua +++ b/rsc/scripts/map_saver.lua @@ -11,5 +11,5 @@ function mapSaver.Save(r) io.write("map_saver:Save(", Region.GetX(r), ", ", Region.GetY(r), ")\n") end ---TODO: create a flexible saving & loading system +--TODO: (9) create a flexible saving & loading system return mapSaver \ No newline at end of file diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index 5109ae8..ddb1826 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -1,10 +1,10 @@ ---TODO: An archive table of all dead characters +--TODO: (9) An archive table of all dead characters CREATE TABLE IF NOT EXISTS Accounts ( uid INTEGER PRIMARY KEY AUTOINCREMENT, - username varchar(100) UNIQUE, --TODO: Swap username for email address + username varchar(100) UNIQUE, --TODO: (9) Swap username for email address - --TODO: server-client security + --server-client security -- passhash varchar(100), -- passsalt varchar(100), @@ -101,5 +101,5 @@ CREATE TABLE IF NOT EXISTS WornEquipment ( --unique information durability INTEGER DEFAULT 0, stats INTEGER REFERENCES StatisticSets(uid) - --TODO: attached script? + --attached script? ); diff --git a/server/accounts/account_data.hpp b/server/accounts/account_data.hpp index c40f281..97df753 100644 --- a/server/accounts/account_data.hpp +++ b/server/accounts/account_data.hpp @@ -47,7 +47,7 @@ private: int clientIndex; std::string username; - //TODO: password + //password/auth token //bit fields? bool blackListed = false; diff --git a/server/monsters/monster_manager.cpp b/server/monsters/monster_manager.cpp index d1f2d45..b0f3d11 100644 --- a/server/monsters/monster_manager.cpp +++ b/server/monsters/monster_manager.cpp @@ -30,45 +30,45 @@ MonsterManager::~MonsterManager() { } int MonsterManager::Create(std::string) { - //TODO: Create + //Create } void MonsterManager::Unload(int uid) { - //TODO: Unload + //Unload } void MonsterManager::UnloadAll() { - //TODO: UnloadAll + //UnloadAll } void MonsterManager::UnloadIf(std::function)> fn) { - //TODO: UnloadIf + //UnloadIf } MonsterData* MonsterManager::Get(int uid) { - //TODO: Get + //Get } int MonsterManager::GetLoadedCount() { - //TODO: GetLoadedCount + //GetLoadedCount } std::map* MonsterManager::GetContainer() { - //TODO: GetContainer + //GetContainer } lua_State* MonsterManager::SetLuaState(lua_State* L) { - //TODO: SetLuaState + //SetLuaState } lua_State* MonsterManager::GetLuaState() { - //TODO: GetLuaState + //GetLuaState } sqlite3* MonsterManager::SetDatabase(sqlite3* db) { - //TODO: SetDatabase + //SetDatabase } sqlite3* MonsterManager::GetDatabase() { - //TODO: GetDatabase + //GetDatabase } diff --git a/server/rooms/room_api.cpp b/server/rooms/room_api.cpp index 19b3a95..ffb9c8a 100644 --- a/server/rooms/room_api.cpp +++ b/server/rooms/room_api.cpp @@ -66,7 +66,6 @@ static int getWaypointMgr(lua_State* L) { } static int initialize(lua_State* L) { - //TODO: This could fit into the room system's globals RoomData* room = static_cast(lua_touserdata(L, 1)); //set the refs of these parameters (backwards, since it pops from the top of the stack) diff --git a/server/rooms/room_manager_api.cpp b/server/rooms/room_manager_api.cpp index 1eade08..1d4ba15 100644 --- a/server/rooms/room_manager_api.cpp +++ b/server/rooms/room_manager_api.cpp @@ -71,7 +71,7 @@ int unloadRoom(lua_State* L) { } int getRoom(lua_State* L) { - //TODO: integer vs name for getRoom() + //integer vs name for getRoom() RoomManager& roomMgr = RoomManager::GetSingleton(); RoomData* room = nullptr; diff --git a/server/server_application.hpp b/server/server_application.hpp index e9a0a41..42ea73b 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -65,46 +65,57 @@ private: //handle incoming traffic void HandlePacket(SerialPacket* const); - //heartbeat sustem - void HandlePing(ServerPacket* const); - void HandlePong(ServerPacket* const); + //heartbeat system + void hPing(ServerPacket* const); + void hPong(ServerPacket* const); //basic connections - void HandleBroadcastRequest(ServerPacket* const); - void HandleJoinRequest(ClientPacket* const); - void HandleLoginRequest(ClientPacket* const); + void hBroadcastRequest(ServerPacket* const); + void hJoinRequest(ClientPacket* const); + void hLoginRequest(ClientPacket* const); //client disconnections - void HandleLogoutRequest(ClientPacket* const); - void HandleDisconnectRequest(ClientPacket* const); + void hLogoutRequest(ClientPacket* const); + void hDisconnectRequest(ClientPacket* const); //server commands - void HandleDisconnectForced(ClientPacket* const); - void HandleShutdownRequest(ClientPacket* const); + void hAdminDisconnectForced(ClientPacket* const); + void hAdminShutdownRequest(ClientPacket* const); //data management - void HandleRegionRequest(RegionPacket* const); - void HandleCharacterExists(CharacterPacket* const); - - void SaveServerState(); - void FullClientUnload(int index); - void FullAccountUnload(int index); - void FullCharacterUnload(int index); + void hRegionRequest(RegionPacket* const); + void hQueryCharacterExists(CharacterPacket* const); + void hQueryCharacterStats(CharacterPacket* const); + void hQueryCharacterLocation(CharacterPacket* const); + void hQueryMonsterExists(MonsterPacket* const); + void hQueryMonsterStats(MonsterPacket* const); + void hQueryMonsterLocation(MonsterPacket* const); //character management - void HandleCharacterCreate(CharacterPacket* const); - void HandleCharacterDelete(CharacterPacket* const); - void HandleCharacterLoad(CharacterPacket* const); - void HandleCharacterUnload(CharacterPacket* const); + void hCharacterCreate(CharacterPacket* const); + void hCharacterDelete(CharacterPacket* const); + void hCharacterLoad(CharacterPacket* const); + void hCharacterUnload(CharacterPacket* const); //character movement - void HandleCharacterMovement(CharacterPacket* const); - void HandleCharacterAttack(CharacterPacket* const); + void hCharacterMovement(CharacterPacket* const); + void hCharacterAttack(CharacterPacket* const); + void hCharacterDamage(CharacterPacket* const); + + //character management + void hMonsterDamage(MonsterPacket* const); + + //chat + void hTextBroadcast(TextPacket* const); //utility methods void PumpPacket(SerialPacket* const); void PumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position, int distance); void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex); + void SaveServerState(); + void FullClientUnload(int index); + void FullAccountUnload(int index); + void FullCharacterUnload(int index); //APIs and utilities sqlite3* database = nullptr; diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index bf302b7..6a4d8b1 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -144,12 +144,12 @@ void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) AccountData* accountData = accountMgr.Get(characterData->GetOwner()); if (!accountData) { - return; //TODO: logic_error + return; } ClientData* clientData = clientMgr.Get(accountData->GetClientIndex()); if (!clientData) { - return; //TODO: logic_error + return; } //check for fraud @@ -175,7 +175,7 @@ void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) //character movement //------------------------- -//TODO: Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments +//TODO: (9) Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments void ServerApplication::HandleCharacterMovement(CharacterPacket* const argPacket) { //get the specified objects @@ -197,7 +197,7 @@ void ServerApplication::HandleCharacterMovement(CharacterPacket* const argPacket //check if allowed if (characterData->GetOwner() != argPacket->accountIndex && !accountData->GetModerator() && !accountData->GetAdministrator()) { - //TODO: send to the client? + //TODO: (9) send to the client? std::cerr << "Failed to set character motion due to lack of permissions targeting uid(" << argPacket->characterIndex << ")" << std::endl; return; } @@ -235,5 +235,5 @@ void ServerApplication::HandleCharacterMovement(CharacterPacket* const argPacket } void ServerApplication::HandleCharacterAttack(CharacterPacket* const) { - //TODO: bounce graphical attack data + //TODO: (9) bounce graphical attack data } \ No newline at end of file diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 12ceda0..a9eeced 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -172,5 +172,5 @@ void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { } void ServerApplication::HandleDisconnectForced(ClientPacket* const argPacket) { - //TODO: HandleDisconnectForced + //HandleDisconnectForced } \ No newline at end of file diff --git a/server/server_data.cpp b/server/server_data.cpp index c8f3c92..2554ba3 100644 --- a/server/server_data.cpp +++ b/server/server_data.cpp @@ -28,10 +28,10 @@ //General data management //------------------------- -//TODO: Queries +//NOTE: Queries go here void ServerApplication::SaveServerState() { - //TODO: SaveServerState + //SaveServerState } //------------------------- diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 23a94d1..c2e7b28 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -128,7 +128,6 @@ void ServerApplication::Init(int argc, char* argv[]) { //debug output //------------------------- - //TODO: enable/disable these with a switch #define DEBUG_OUTPUT_VAR(x) std::cout << "\t" << #x << ": " << x << std::endl; std::cout << "Internal sizes:" << std::endl; @@ -195,7 +194,7 @@ void ServerApplication::Proc() { void ServerApplication::Quit() { std::cout << "Shutting down" << std::endl; - //TODO: save the server state + //TODO: (9) save the server state //close the managers accountMgr.UnloadAll(); @@ -221,84 +220,96 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { switch(argPacket->type) { //heartbeat system case SerialPacketType::PING: - HandlePing(static_cast(argPacket)); + hPing(static_cast(argPacket)); break; case SerialPacketType::PONG: - HandlePong(static_cast(argPacket)); + hPong(static_cast(argPacket)); break; //client connections case SerialPacketType::BROADCAST_REQUEST: - HandleBroadcastRequest(static_cast(argPacket)); + hBroadcastRequest(static_cast(argPacket)); break; case SerialPacketType::JOIN_REQUEST: - HandleJoinRequest(static_cast(argPacket)); + hJoinRequest(static_cast(argPacket)); break; case SerialPacketType::LOGIN_REQUEST: - HandleLoginRequest(static_cast(argPacket)); + hLoginRequest(static_cast(argPacket)); break; //client disconnections case SerialPacketType::LOGOUT_REQUEST: - HandleLogoutRequest(static_cast(argPacket)); + hLogoutRequest(static_cast(argPacket)); break; case SerialPacketType::DISCONNECT_REQUEST: - HandleDisconnectRequest(static_cast(argPacket)); + hDisconnectRequest(static_cast(argPacket)); break; //server commands -// case SerialPacketType::DISCONNECT_FORCED: -// HandleDisconnectForced(static_cast(argPacket)); -// break; - case SerialPacketType::SHUTDOWN_REQUEST: - HandleShutdownRequest(static_cast(argPacket)); + case SerialPacketType::ADMIN_DISCONNECT_FORCED: + hAdminDisconnectForced(static_cast(argPacket)); + break; + case SerialPacketType::ADMIN_SHUTDOWN_REQUEST: + hAdminShutdownRequest(static_cast(argPacket)); break; //data management & queries case SerialPacketType::REGION_REQUEST: - HandleRegionRequest(static_cast(argPacket)); + hRegionRequest(static_cast(argPacket)); break; case SerialPacketType::QUERY_CHARACTER_EXISTS: - HandleCharacterExists(static_cast(argPacket)); + hQueryCharacterExists(static_cast(argPacket)); break; + case SerialPacketType::QUERY_CHARACTER_STATS: + hQueryCharacterStats(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_LOCATION: + hQueryCharacterLocation(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_EXISTS: -// HandleMonsterExists(static_cast(argPacket)); + hQueryMonsterExists(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_STATS: + hQueryMonsterStats(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_LOCATION: + hQueryMonsterLocation(static_cast(argPacket)); break; //character management case SerialPacketType::CHARACTER_CREATE: - HandleCharacterCreate(static_cast(argPacket)); + hCharacterCreate(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(static_cast(argPacket)); + hCharacterDelete(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_LOAD: - HandleCharacterLoad(static_cast(argPacket)); + hCharacterLoad(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_UNLOAD: - HandleCharacterUnload(static_cast(argPacket)); + hCharacterUnload(static_cast(argPacket)); break; //character movement case SerialPacketType::CHARACTER_MOVEMENT: - HandleCharacterMovement(static_cast(argPacket)); + hCharacterMovement(static_cast(argPacket)); break; case SerialPacketType::CHARACTER_ATTACK: - HandleCharacterAttack(static_cast(argPacket)); + hCharacterAttack(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_DAMAGE: + hCharacterDamage(static_cast(argPacket)); break; //monster management - case SerialPacketType::MONSTER_CREATE: -// HandleMonsterCreate(static_cast(argPacket)); + case SerialPacketType::MONSTER_DAMAGE: + hMonsterDamage(static_cast(argPacket)); break; - case SerialPacketType::MONSTER_DELETE: -// HandleMonsterDelete(static_cast(argPacket)); - break; - case SerialPacketType::MONSTER_MOVEMENT: -// HandleMonsterMovement(static_cast(argPacket)); - break; - case SerialPacketType::MONSTER_ATTACK: -// HandleMonsterAttack(static_cast(argPacket)); + + //chat + case SerialPacketType::TEXT_BROADCAST: + hTextBroadcast(static_cast(argPacket)); break; //handle errors diff --git a/server/waypoints/waypoint_manager_api.cpp b/server/waypoints/waypoint_manager_api.cpp index d8ce4fa..a88dc48 100644 --- a/server/waypoints/waypoint_manager_api.cpp +++ b/server/waypoints/waypoint_manager_api.cpp @@ -27,12 +27,10 @@ static int create(lua_State* L) { WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); - //TODO: create } static int unload(lua_State* L) { WaypointManager* mgr = static_cast(lua_touserdata(L, 1)); - //TODO: create } static int getWaypoint(lua_State* L) { diff --git a/todo.txt b/todo.txt index c4582aa..eca1dfc 100644 --- a/todo.txt +++ b/todo.txt @@ -7,16 +7,21 @@ TODO: Account passwords (list) * ... * salts & hashes -TODO: Make sure login errors are sent to the client -TODO: Split config.cfg in two, one for the server and the client -TODO: Add the "home" parameter to the server's config file -TODO: Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. -TODO: Fix shoddy movement -TODO: Periodic mass server saves -TODO: Remove the big "Shut Down" button (currently broken...) -TODO: Make a way for the server owner to control the server directly -TODO: The TileSheet class should implement the surface itself -TODO: Time delay for requesting region packets -TODO: A proper logging system -TODO: Fix the const-ness of accessors -TODO: Add a screenshot of the game to README.md \ No newline at end of file +TODO: Features + * Make sure login errors are sent to the client + * Split config.cfg in two, one for the server and the client + * Add the "home" parameter to the server's config file + * Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. + * Fix shoddy movement + * Periodic mass server saves + * Remove the big "Shut Down" button (currently broken...) + * Make a way for the server owner to control the server directly + * The TileSheet class should implement the surface itself + * Time delay for requesting region packets + * A proper logging system + * Fix the const-ness of accessors + * Add a screenshot of the game to README.md + * joystick/gamepad support + * add the tilesheet to the map system + * ping/delay displayed in the lobby + * login screen prompting for username & password \ No newline at end of file From 9710acad6f8bb05e443d9765f2c2abd0f8139b3a Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 13 Feb 2015 02:57:36 +1100 Subject: [PATCH 18/21] Lost focus --- server/server_connections.cpp | 18 +++++++----------- server/server_methods.cpp | 4 ++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/server/server_connections.cpp b/server/server_connections.cpp index a9eeced..36c5bf0 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -28,13 +28,13 @@ //heartbeat system //------------------------- -void ServerApplication::HandlePing(ServerPacket* const argPacket) { +void ServerApplication::hPing(ServerPacket* const argPacket) { ServerPacket newPacket; newPacket.type = SerialPacketType::PONG; network.SendTo(argPacket->srcAddress, &newPacket); } -void ServerApplication::HandlePong(ServerPacket* const argPacket) { +void ServerApplication::hPong(ServerPacket* const argPacket) { clientMgr.HandlePong(argPacket); } @@ -42,7 +42,7 @@ void ServerApplication::HandlePong(ServerPacket* const argPacket) { //basic connections //------------------------- -void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { +void ServerApplication::hBroadcastRequest(ServerPacket* const argPacket) { //send the server's data ServerPacket newPacket; @@ -54,7 +54,7 @@ void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } -void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { +void ServerApplication::hJoinRequest(ClientPacket* const argPacket) { //register the client int clientIndex = clientMgr.Create(argPacket->srcAddress); @@ -69,7 +69,7 @@ void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) { std::cout << "New join, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } -void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) { +void ServerApplication::hLoginRequest(ClientPacket* const argPacket) { //get the client data ClientData* clientData = clientMgr.Get(argPacket->clientIndex); @@ -110,7 +110,7 @@ void ServerApplication::HandleLoginRequest(ClientPacket* const argPacket) { std::cout << "New login, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } -void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) { +void ServerApplication::hLogoutRequest(ClientPacket* const argPacket) { //get the account and client data AccountData* accountData = accountMgr.Get(argPacket->accountIndex); if (!accountData) { @@ -144,7 +144,7 @@ void ServerApplication::HandleLogoutRequest(ClientPacket* const argPacket) { std::cout << "New logout, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } -void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { +void ServerApplication::hDisconnectRequest(ClientPacket* const argPacket) { //get the client data ClientData* clientData = clientMgr.Get(argPacket->clientIndex); if (!clientData) { @@ -170,7 +170,3 @@ void ServerApplication::HandleDisconnectRequest(ClientPacket* const argPacket) { //finished this routine std::cout << "New disconnection, " << clientMgr.GetLoadedCount() << " clients and " << accountMgr.GetLoadedCount() << " accounts total" << std::endl; } - -void ServerApplication::HandleDisconnectForced(ClientPacket* const argPacket) { - //HandleDisconnectForced -} \ No newline at end of file diff --git a/server/server_methods.cpp b/server/server_methods.cpp index 2bd79c0..4c490b6 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -29,6 +29,10 @@ //server commands //------------------------- +void ServerApplication::hAdminDisconnectForced(ClientPacket* const argPacket) { + //TODO: (9) boot players +} + void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { //get the account and client data AccountData* accountData = accountMgr.Get(argPacket->accountIndex); From e71d0b3a098fb8b3a796196a043e6265763c7355 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 13 Feb 2015 23:34:34 +1100 Subject: [PATCH 19/21] Finished these server tweaks --- common/network/packet_types/text_packet.cpp | 12 +++++++ common/network/packet_types/text_packet.hpp | 5 +++ common/network/serial_packet_type.hpp | 2 ++ common/network/serial_utility.cpp | 4 +++ server/server_application.hpp | 2 ++ server/server_character_methods.cpp | 16 +++++---- server/server_chat.cpp | 34 ++++++++++++++++++ ...erver_data.cpp => server_data_queries.cpp} | 36 ++++++++++++------- server/server_logic.cpp | 6 ++++ server/server_methods.cpp | 4 +-- server/server_monster_methods.cpp | 3 ++ 11 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 server/server_chat.cpp rename server/{server_data.cpp => server_data_queries.cpp} (80%) diff --git a/common/network/packet_types/text_packet.cpp b/common/network/packet_types/text_packet.cpp index 56a9836..2ec8ce2 100644 --- a/common/network/packet_types/text_packet.cpp +++ b/common/network/packet_types/text_packet.cpp @@ -29,6 +29,12 @@ void serializeText(void* buffer, TextPacket* packet) { //content serialCopy(&buffer, packet->name, PACKET_STRING_SIZE); serialCopy(&buffer, packet->text, PACKET_STRING_SIZE); + + //location + serialCopy(&buffer, &packet->roomIndex, sizeof(int)); + serialCopy(&buffer, &packet->origin.x, sizeof(double)); + serialCopy(&buffer, &packet->origin.y, sizeof(double)); + serialCopy(&buffer, &packet->range, sizeof(int)); } void deserializeText(void* buffer, TextPacket* packet) { @@ -37,4 +43,10 @@ void deserializeText(void* buffer, TextPacket* packet) { //content deserialCopy(&buffer, packet->name, PACKET_STRING_SIZE); deserialCopy(&buffer, packet->text, PACKET_STRING_SIZE); + + //location + deserialCopy(&buffer, &packet->roomIndex, sizeof(int)); + deserialCopy(&buffer, &packet->origin.x, sizeof(double)); + deserialCopy(&buffer, &packet->origin.y, sizeof(double)); + deserialCopy(&buffer, &packet->range, sizeof(int)); } \ No newline at end of file diff --git a/common/network/packet_types/text_packet.hpp b/common/network/packet_types/text_packet.hpp index 0e793b6..9b9ae4b 100644 --- a/common/network/packet_types/text_packet.hpp +++ b/common/network/packet_types/text_packet.hpp @@ -24,9 +24,14 @@ #include "serial_packet_base.hpp" +#include "vector2.hpp" + struct TextPacket : SerialPacketBase { char name[PACKET_STRING_SIZE]; char text[PACKET_STRING_SIZE]; + int roomIndex; + Vector2 origin; + int range; }; void serializeText(void* buffer, TextPacket* packet); diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index d8b76e7..cd798ab 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -131,6 +131,8 @@ enum class SerialPacketType { //general speech TEXT_BROADCAST, + TEXT_SPEECH, + TEXT_WHISPER, //rejection/error messages JOIN_REJECTION, diff --git a/common/network/serial_utility.cpp b/common/network/serial_utility.cpp index a584ad0..7159b10 100644 --- a/common/network/serial_utility.cpp +++ b/common/network/serial_utility.cpp @@ -92,6 +92,8 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { serializeMonster(buffer, static_cast(packet)); break; case SerialPacketType::TEXT_BROADCAST: + case SerialPacketType::TEXT_SPEECH: + case SerialPacketType::TEXT_WHISPER: case SerialPacketType::JOIN_REJECTION: case SerialPacketType::LOGIN_REJECTION: case SerialPacketType::REGION_REJECTION: @@ -154,6 +156,8 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { deserializeMonster(buffer, static_cast(packet)); break; case SerialPacketType::TEXT_BROADCAST: + case SerialPacketType::TEXT_SPEECH: + case SerialPacketType::TEXT_WHISPER: case SerialPacketType::JOIN_REJECTION: case SerialPacketType::LOGIN_REJECTION: case SerialPacketType::REGION_REJECTION: diff --git a/server/server_application.hpp b/server/server_application.hpp index 42ea73b..d53ed32 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -107,6 +107,8 @@ private: //chat void hTextBroadcast(TextPacket* const); + void hTextSpeech(TextPacket* const); + void hTextWhisper(TextPacket* const); //utility methods void PumpPacket(SerialPacket* const); diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index 6a4d8b1..5c76f83 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -28,7 +28,7 @@ //Character Management //------------------------- -void ServerApplication::HandleCharacterCreate(CharacterPacket* const argPacket) { +void ServerApplication::hCharacterCreate(CharacterPacket* const argPacket) { int characterIndex = characterMgr.Create(argPacket->accountIndex, argPacket->handle, argPacket->avatar); if (characterIndex < 0) { @@ -55,7 +55,7 @@ void ServerApplication::HandleCharacterCreate(CharacterPacket* const argPacket) PumpPacket(&newPacket); } -void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) { +void ServerApplication::hCharacterDelete(CharacterPacket* const argPacket) { //get the user's data AccountData* accountData = accountMgr.Get(argPacket->accountIndex); if (!accountData) { @@ -102,7 +102,7 @@ void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) PumpPacket(static_cast(&newPacket)); } -void ServerApplication::HandleCharacterLoad(CharacterPacket* const argPacket) { +void ServerApplication::hCharacterLoad(CharacterPacket* const argPacket) { int characterIndex = characterMgr.Load(argPacket->accountIndex, argPacket->handle, argPacket->avatar); if (characterIndex < 0) { @@ -135,7 +135,7 @@ void ServerApplication::HandleCharacterLoad(CharacterPacket* const argPacket) { PumpPacket(&newPacket); } -void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) { +void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { //get the entries CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); if (!characterData) { @@ -177,7 +177,7 @@ void ServerApplication::HandleCharacterUnload(CharacterPacket* const argPacket) //TODO: (9) Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments -void ServerApplication::HandleCharacterMovement(CharacterPacket* const argPacket) { +void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { //get the specified objects AccountData* accountData = accountMgr.Get(argPacket->accountIndex); CharacterData* characterData = characterMgr.Get(argPacket->characterIndex); @@ -234,6 +234,10 @@ void ServerApplication::HandleCharacterMovement(CharacterPacket* const argPacket } } -void ServerApplication::HandleCharacterAttack(CharacterPacket* const) { +void ServerApplication::hCharacterAttack(CharacterPacket* const argPacket) { //TODO: (9) bounce graphical attack data +} + +void ServerApplication::hCharacterDamage(CharacterPacket* const argPacket) { + //TODO: (9) empty } \ No newline at end of file diff --git a/server/server_chat.cpp b/server/server_chat.cpp new file mode 100644 index 0000000..ed9c4e4 --- /dev/null +++ b/server/server_chat.cpp @@ -0,0 +1,34 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "server_application.hpp" + +void ServerApplication::hTextBroadcast(TextPacket* const argPacket) { + //TODO: (9) empty +} + +void ServerApplication::hTextSpeech(TextPacket* const argPacket) { + //TODO: (9) empty +} + +void ServerApplication::hTextWhisper(TextPacket* const argPacket) { + //TODO: (9) empty +} diff --git a/server/server_data.cpp b/server/server_data_queries.cpp similarity index 80% rename from server/server_data.cpp rename to server/server_data_queries.cpp index 2554ba3..1019223 100644 --- a/server/server_data.cpp +++ b/server/server_data_queries.cpp @@ -25,20 +25,10 @@ #include //------------------------- -//General data management +//Queries //------------------------- -//NOTE: Queries go here - -void ServerApplication::SaveServerState() { - //SaveServerState -} - -//------------------------- -//Map management -//------------------------- - -void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { +void ServerApplication::hRegionRequest(RegionPacket* const argPacket) { //get the region object, send a rejection on error RoomData* room = roomMgr.Get(argPacket->roomIndex); if (!room) { @@ -71,7 +61,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) { network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } -void ServerApplication::HandleCharacterExists(CharacterPacket* const argPacket) { +void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket) { //respond with all character data CharacterPacket newPacket; @@ -84,3 +74,23 @@ void ServerApplication::HandleCharacterExists(CharacterPacket* const argPacket) network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } } + +void ServerApplication::hQueryCharacterStats(CharacterPacket* const argPacket) { + //TODO: (9) empty +} + +void ServerApplication::hQueryCharacterLocation(CharacterPacket* const argPacket) { + //TODO: (9) empty +} + +void ServerApplication::hQueryMonsterExists(MonsterPacket* const argPacket) { + //TODO: (9) empty +} + +void ServerApplication::hQueryMonsterStats(MonsterPacket* const argPacket) { + //TODO: (9) empty +} + +void ServerApplication::hQueryMonsterLocation(MonsterPacket* const argPacket) { + //TODO: (9) empty +} diff --git a/server/server_logic.cpp b/server/server_logic.cpp index c2e7b28..83ee0b6 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -311,6 +311,12 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) { case SerialPacketType::TEXT_BROADCAST: hTextBroadcast(static_cast(argPacket)); break; + case SerialPacketType::TEXT_SPEECH: + hTextSpeech(static_cast(argPacket)); + break; + case SerialPacketType::TEXT_WHISPER: + hTextWhisper(static_cast(argPacket)); + break; //handle errors default: { diff --git a/server/server_methods.cpp b/server/server_methods.cpp index 4c490b6..0b55219 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -33,7 +33,7 @@ void ServerApplication::hAdminDisconnectForced(ClientPacket* const argPacket) { //TODO: (9) boot players } -void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { +void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { //get the account and client data AccountData* accountData = accountMgr.Get(argPacket->accountIndex); if (!accountData) { @@ -76,7 +76,7 @@ void ServerApplication::HandleShutdownRequest(ClientPacket* const argPacket) { //disconnect all clients TextPacket newPacket; - newPacket.type = SerialPacketType::DISCONNECT_FORCED; + newPacket.type = SerialPacketType::ADMIN_DISCONNECT_FORCED; strncpy(newPacket.text, "Server shutdown", PACKET_STRING_SIZE); PumpPacket(&newPacket); diff --git a/server/server_monster_methods.cpp b/server/server_monster_methods.cpp index 3079d7a..ae8ba43 100644 --- a/server/server_monster_methods.cpp +++ b/server/server_monster_methods.cpp @@ -21,3 +21,6 @@ */ #include "server_application.hpp" +void ServerApplication::hMonsterDamage(MonsterPacket* const argPacket) { + //TODO: (9) empty +} \ No newline at end of file From 18b144fa4604a494711714a7a44cf70d5a8cfa77 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Feb 2015 23:39:56 +1100 Subject: [PATCH 20/21] Updated client, read more It seems like the project as a whole is fairly stable now. I'm prepping to merge this into master, despite the lack of monsters ATM. Hopefully this break hasn't affected the stability too much. --- client/client_application.cpp | 6 +- .../gameplay_scenes/in_world_networking.cpp | 264 ------------------ .../{in_world.hpp => world.hpp} | 66 +++-- ...ld_characters.cpp => world_characters.cpp} | 30 +- client/gameplay_scenes/world_chat.cpp | 39 +++ client/gameplay_scenes/world_connections.cpp | 135 +++++++++ .../{in_world_scene.cpp => world_logic.cpp} | 147 ++++++++-- client/gameplay_scenes/world_map.cpp | 79 ++++++ ..._world_monsters.cpp => world_monsters.cpp} | 24 +- client/menu_scenes/lobby_menu.cpp | 2 +- client/menu_scenes/main_menu.cpp | 6 +- client/scene_list.hpp | 2 +- common/network/serial_packet_type.hpp | 1 + common/network/serial_utility.cpp | 2 + server/server_logic.cpp | 2 +- 15 files changed, 476 insertions(+), 329 deletions(-) delete mode 100644 client/gameplay_scenes/in_world_networking.cpp rename client/gameplay_scenes/{in_world.hpp => world.hpp} (68%) rename client/gameplay_scenes/{in_world_characters.cpp => world_characters.cpp} (88%) create mode 100644 client/gameplay_scenes/world_chat.cpp create mode 100644 client/gameplay_scenes/world_connections.cpp rename client/gameplay_scenes/{in_world_scene.cpp => world_logic.cpp} (62%) create mode 100644 client/gameplay_scenes/world_map.cpp rename client/gameplay_scenes/{in_world_monsters.cpp => world_monsters.cpp} (84%) diff --git a/client/client_application.cpp b/client/client_application.cpp index 21ad65e..caf465d 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -37,7 +37,7 @@ #include "main_menu.hpp" #include "options_menu.hpp" #include "lobby_menu.hpp" -#include "in_world.hpp" +#include "world.hpp" #include "disconnected_screen.hpp" //------------------------- @@ -185,8 +185,8 @@ void ClientApplication::LoadScene(SceneList sceneIndex) { case SceneList::LOBBYMENU: activeScene = new LobbyMenu(&clientIndex, &accountIndex); break; - case SceneList::INWORLD: - activeScene = new InWorld(&clientIndex, &accountIndex); + case SceneList::WORLD: + activeScene = new World(&clientIndex, &accountIndex); break; case SceneList::DISCONNECTEDSCREEN: activeScene = new DisconnectedScreen(); diff --git a/client/gameplay_scenes/in_world_networking.cpp b/client/gameplay_scenes/in_world_networking.cpp deleted file mode 100644 index db23ce1..0000000 --- a/client/gameplay_scenes/in_world_networking.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013-2015 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#include "in_world.hpp" - -#include "channels.hpp" -#include "ip_operators.hpp" -#include "terminal_error.hpp" - -#include -#include -#include - -//------------------------- -//Basic connections -//------------------------- - -void InWorld::HandlePacket(SerialPacket* const argPacket) { - switch(argPacket->type) { - //heartbeat system - case SerialPacketType::PING: - HandlePing(static_cast(argPacket)); - break; - case SerialPacketType::PONG: - HandlePong(static_cast(argPacket)); - break; - - //game server connections - case SerialPacketType::LOGOUT_RESPONSE: - HandleLogoutResponse(static_cast(argPacket)); - break; - case SerialPacketType::DISCONNECT_RESPONSE: - HandleDisconnectResponse(static_cast(argPacket)); - break; - case SerialPacketType::DISCONNECT_FORCED: - HandleDisconnectForced(static_cast(argPacket)); - break; - - //map management - case SerialPacketType::REGION_CONTENT: - HandleRegionContent(static_cast(argPacket)); - break; - - //character management - case SerialPacketType::CHARACTER_CREATE: - HandleCharacterCreate(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_DELETE: - HandleCharacterDelete(static_cast(argPacket)); - break; - case SerialPacketType::QUERY_CHARACTER_EXISTS: - HandleCharacterQueryExists(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_MOVEMENT: - HandleCharacterMovement(static_cast(argPacket)); - break; - case SerialPacketType::CHARACTER_ATTACK: - HandleCharacterAttack(static_cast(argPacket)); - break; - - //monster management - case SerialPacketType::MONSTER_CREATE: - HandleMonsterCreate(static_cast(argPacket)); - break; - case SerialPacketType::MONSTER_DELETE: - HandleMonsterDelete(static_cast(argPacket)); - break; - case SerialPacketType::QUERY_MONSTER_EXISTS: - HandleMonsterQueryExists(static_cast(argPacket)); - break; - case SerialPacketType::MONSTER_MOVEMENT: - HandleMonsterMovement(static_cast(argPacket)); - break; - case SerialPacketType::MONSTER_ATTACK: - HandleMonsterAttack(static_cast(argPacket)); - break; - - //rejection messages - case SerialPacketType::REGION_REJECTION: - case SerialPacketType::CHARACTER_REJECTION: - throw(terminal_error(static_cast(argPacket)->text)); - break; - case SerialPacketType::SHUTDOWN_REJECTION: - throw(std::runtime_error(static_cast(argPacket)->text)); - break; - - //errors - default: { - std::ostringstream msg; - msg << "Unknown SerialPacketType encountered in InWorld: " << static_cast(argPacket->type); - throw(std::runtime_error(msg.str())); - } - break; - } -} - -void InWorld::HandlePing(ServerPacket* const argPacket) { - ServerPacket newPacket; - newPacket.type = SerialPacketType::PONG; - network.SendTo(argPacket->srcAddress, &newPacket); -} - -void InWorld::HandlePong(ServerPacket* const argPacket) { - if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) { - throw(std::runtime_error("Heartbeat message received from an unknown source")); - } - attemptedBeats = 0; - lastBeat = Clock::now(); -} - -//------------------------- -//Connection control -//------------------------- - -void InWorld::SendLogoutRequest() { - ClientPacket newPacket; - - //send a logout request - newPacket.type = SerialPacketType::LOGOUT_REQUEST; - newPacket.accountIndex = accountIndex; - - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::SendDisconnectRequest() { - ClientPacket newPacket; - - //send a disconnect request - newPacket.type = SerialPacketType::DISCONNECT_REQUEST; - newPacket.clientIndex = clientIndex; - - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::SendShutdownRequest() { - ClientPacket newPacket; - - //send a shutdown request - newPacket.type = SerialPacketType::SHUTDOWN_REQUEST; - newPacket.accountIndex = accountIndex; - - network.SendTo(Channels::SERVER, &newPacket); -} - -void InWorld::HandleLogoutResponse(ClientPacket* const argPacket) { - if (localCharacter) { - characterMap.erase(characterIndex); - localCharacter = nullptr; - } - - accountIndex = -1; - characterIndex = -1; - - //reset the camera - camera.marginX = camera.marginY = 0; - - //because, why not? I guess... - SendDisconnectRequest(); -} - -void InWorld::HandleDisconnectResponse(ClientPacket* const argPacket) { - HandleLogoutResponse(argPacket);//shortcut - SetNextScene(SceneList::DISCONNECTEDSCREEN); - ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have successfully logged out"; -} - -void InWorld::HandleDisconnectForced(ClientPacket* const argPacket) { - HandleDisconnectResponse(argPacket);//shortcut - SetNextScene(SceneList::DISCONNECTEDSCREEN); - ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server"; -} - -void InWorld::CheckHeartBeat() { - //check the connection (heartbeat) - if (Clock::now() - lastBeat > std::chrono::seconds(3)) { - if (attemptedBeats > 2) { - //escape to the disconnect screen - SendDisconnectRequest(); - SetNextScene(SceneList::DISCONNECTEDSCREEN); - ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server"; - } - else { - ServerPacket newPacket; - newPacket.type = SerialPacketType::PING; - network.SendTo(Channels::SERVER, &newPacket); - - attemptedBeats++; - lastBeat = Clock::now(); - } - } -} - -//------------------------- -//map management -//------------------------- - -void InWorld::SendRegionRequest(int roomIndex, int x, int y) { - RegionPacket packet; - - //pack the region's data - packet.type = SerialPacketType::REGION_REQUEST; - packet.roomIndex = roomIndex; - packet.x = x; - packet.y = y; - - network.SendTo(Channels::SERVER, &packet); -} - -void InWorld::HandleRegionContent(RegionPacket* const argPacket) { - //replace existing regions - regionPager.UnloadIf([&](Region const& region) -> bool { - return region.GetX() == argPacket->x && region.GetY() == argPacket->y; - }); - regionPager.PushRegion(argPacket->region); - - //clean up after the serial code - delete argPacket->region; - argPacket->region = nullptr; -} - -void InWorld::UpdateMap() { - if (roomIndex == -1) { - return; - } - - //these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1) - int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH; - int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH; - - int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT; - int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT; - - //prune distant regions - regionPager.GetContainer()->remove_if([&](Region const& region) -> bool { - return region.GetX() < xStart || region.GetX() > xEnd || region.GetY() < yStart || region.GetY() > yEnd; - }); - - //request empty regions within this zone - for (int i = xStart; i <= xEnd; i += REGION_WIDTH) { - for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) { - if (!regionPager.FindRegion(i, j)) { - SendRegionRequest(roomIndex, i, j); - } - } - } -} \ No newline at end of file diff --git a/client/gameplay_scenes/in_world.hpp b/client/gameplay_scenes/world.hpp similarity index 68% rename from client/gameplay_scenes/in_world.hpp rename to client/gameplay_scenes/world.hpp index bbf4705..cc2135a 100644 --- a/client/gameplay_scenes/in_world.hpp +++ b/client/gameplay_scenes/world.hpp @@ -49,11 +49,11 @@ #include -class InWorld : public BaseScene { +class World: public BaseScene { public: //Public access members - InWorld(int* const argClientIndex, int* const argAccountIndex); - ~InWorld(); + World(int* const argClientIndex, int* const argAccountIndex); + ~World(); protected: //Frame loop @@ -71,42 +71,56 @@ protected: void KeyDown(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&); - //Basic connections + //handle incoming traffic void HandlePacket(SerialPacket* const); - void HandlePing(ServerPacket* const); - void HandlePong(ServerPacket* const); - //Connection control - void SendLogoutRequest(); - void SendDisconnectRequest(); - void SendShutdownRequest(); - - void HandleLogoutResponse(ClientPacket* const); - void HandleDisconnectResponse(ClientPacket* const); - void HandleDisconnectForced(ClientPacket* const); + //heartbeat system + void hPing(ServerPacket* const); + void hPong(ServerPacket* const); void CheckHeartBeat(); + //basic connections + void SendLogoutRequest(); + void SendDisconnectRequest(); + void SendAdminDisconnectForced(); + void SendAdminShutdownRequest(); + + void hLogoutResponse(ClientPacket* const); + void hDisconnectResponse(ClientPacket* const); + void hAdminDisconnectForced(ClientPacket* const); + //map management void SendRegionRequest(int roomIndex, int x, int y); - void HandleRegionContent(RegionPacket* const); + void hRegionContent(RegionPacket* const); void UpdateMap(); //character management - void HandleCharacterCreate(CharacterPacket* const); - void HandleCharacterDelete(CharacterPacket* const); - void HandleCharacterQueryExists(CharacterPacket* const); - void HandleCharacterMovement(CharacterPacket* const); - void HandleCharacterAttack(CharacterPacket* const); + void hCharacterCreate(CharacterPacket* const); + void hCharacterDelete(CharacterPacket* const); + void hQueryCharacterExists(CharacterPacket* const); + void hQueryCharacterStats(CharacterPacket* const); + void hQueryCharacterLocation(CharacterPacket* const); + void hCharacterMovement(CharacterPacket* const); + void hCharacterAttack(CharacterPacket* const); + void hCharacterDamage(CharacterPacket* const); //monster management - void HandleMonsterCreate(MonsterPacket* const); - void HandleMonsterDelete(MonsterPacket* const); - void HandleMonsterQueryExists(MonsterPacket* const); - void HandleMonsterMovement(MonsterPacket* const); - void HandleMonsterAttack(MonsterPacket* const); + void hMonsterCreate(MonsterPacket* const); + void hMonsterDelete(MonsterPacket* const); + void hQueryMonsterExists(MonsterPacket* const); + void hQueryMonsterStats(MonsterPacket* const); + void hQueryMonsterLocation(MonsterPacket* const); + void hMonsterMovement(MonsterPacket* const); + void hMonsterAttack(MonsterPacket* const); + void hMonsterDamage(MonsterPacket* const); - //player movement + //chat + void hTextBroadcast(TextPacket* const); + void hTextSpeech(TextPacket* const); + void hTextWhisper(TextPacket* const); + + //general gameplay void SendLocalCharacterMovement(); std::list GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight); diff --git a/client/gameplay_scenes/in_world_characters.cpp b/client/gameplay_scenes/world_characters.cpp similarity index 88% rename from client/gameplay_scenes/in_world_characters.cpp rename to client/gameplay_scenes/world_characters.cpp index 328cfd7..8512e76 100644 --- a/client/gameplay_scenes/in_world_characters.cpp +++ b/client/gameplay_scenes/world_characters.cpp @@ -19,7 +19,7 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "in_world.hpp" +#include "world.hpp" #include "channels.hpp" @@ -35,7 +35,7 @@ //DOCS: new characters will result in create messages //DOCS: this client's character will exist in both (skipped) -void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { +void World::hCharacterCreate(CharacterPacket* const argPacket) { //prevent double message if (characterMap.find(argPacket->characterIndex) != characterMap.end()) { std::ostringstream msg; @@ -74,7 +74,7 @@ void InWorld::HandleCharacterCreate(CharacterPacket* const argPacket) { std::cout << "Character Create, total: " << characterMap.size() << std::endl; } -void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { +void World::hCharacterDelete(CharacterPacket* const argPacket) { //ignore if this character doesn't exist std::map::iterator characterIt = characterMap.find(argPacket->characterIndex); if (characterIt == characterMap.end()) { @@ -100,7 +100,7 @@ void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) { std::cout << "Character Delete, total: " << characterMap.size() << std::endl; } -void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { +void World::hQueryCharacterExists(CharacterPacket* const argPacket) { //prevent a double message about this player's character if (argPacket->accountIndex == accountIndex) { return; @@ -127,7 +127,15 @@ void InWorld::HandleCharacterQueryExists(CharacterPacket* const argPacket) { std::cout << "Character Query, total: " << characterMap.size() << std::endl; } -void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { +void World::hQueryCharacterStats(CharacterPacket* const argPacket) { + //TODO: empty +} + +void World::hQueryCharacterLocation(CharacterPacket* const argPacket) { + //TODO: empty +} + +void World::hCharacterMovement(CharacterPacket* const argPacket) { //TODO: (1) Authentication if (argPacket->characterIndex == characterIndex) { return; @@ -143,15 +151,19 @@ void InWorld::HandleCharacterMovement(CharacterPacket* const argPacket) { } } -void InWorld::HandleCharacterAttack(CharacterPacket* const argPacket) { +void World::hCharacterAttack(CharacterPacket* const argPacket) { + //TODO: (1) attack animation +} + +void World::hCharacterDamage(CharacterPacket* const argPacket) { //TODO: (1) attack animation } //------------------------- -//player movement +//player movement & collision //------------------------- -void InWorld::SendLocalCharacterMovement() { +void World::SendLocalCharacterMovement() { CharacterPacket newPacket; newPacket.type = SerialPacketType::CHARACTER_MOVEMENT; @@ -164,7 +176,7 @@ void InWorld::SendLocalCharacterMovement() { network.SendTo(Channels::SERVER, &newPacket); } -std::list InWorld::GenerateCollisionGrid(Entity* ptr, int tileWidth, int tileHeight) { +std::list World::GenerateCollisionGrid(Entity* ptr, int tileWidth, int tileHeight) { //prepare for collisions BoundingBox wallBounds = {0, 0, tileWidth, tileHeight}; std::list boxList; diff --git a/client/gameplay_scenes/world_chat.cpp b/client/gameplay_scenes/world_chat.cpp new file mode 100644 index 0000000..9386478 --- /dev/null +++ b/client/gameplay_scenes/world_chat.cpp @@ -0,0 +1,39 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "world.hpp" + +//------------------------- +//chat +//------------------------- + +void World::hTextBroadcast(TextPacket* const argPacket) { + //TODO: (1) empty +} + +void World::hTextSpeech(TextPacket* const argPacket) { + //TODO: (1) empty +} + +void World::hTextWhisper(TextPacket* const argPacket) { + //TODO: (1) empty +} + diff --git a/client/gameplay_scenes/world_connections.cpp b/client/gameplay_scenes/world_connections.cpp new file mode 100644 index 0000000..c20c101 --- /dev/null +++ b/client/gameplay_scenes/world_connections.cpp @@ -0,0 +1,135 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "world.hpp" + +#include "channels.hpp" +#include "ip_operators.hpp" + +#include +#include +#include + +//------------------------- +//heartbeat system +//------------------------- + +void World::hPing(ServerPacket* const argPacket) { + ServerPacket newPacket; + newPacket.type = SerialPacketType::PONG; + network.SendTo(argPacket->srcAddress, &newPacket); +} + +void World::hPong(ServerPacket* const argPacket) { + if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) { + throw(std::runtime_error("Heartbeat message received from an unknown source")); + } + attemptedBeats = 0; + lastBeat = Clock::now(); +} + +void World::CheckHeartBeat() { + //check the connection (heartbeat) + if (Clock::now() - lastBeat > std::chrono::seconds(3)) { + if (attemptedBeats > 2) { + //escape to the disconnect screen + SendDisconnectRequest(); + SetNextScene(SceneList::DISCONNECTEDSCREEN); + ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server"; + } + else { + ServerPacket newPacket; + newPacket.type = SerialPacketType::PING; + network.SendTo(Channels::SERVER, &newPacket); + + attemptedBeats++; + lastBeat = Clock::now(); + } + } +} + +//------------------------- +//Connection control +//------------------------- + +void World::SendLogoutRequest() { + ClientPacket newPacket; + + //send a logout request + newPacket.type = SerialPacketType::LOGOUT_REQUEST; + newPacket.accountIndex = accountIndex; + + network.SendTo(Channels::SERVER, &newPacket); +} + +void World::SendDisconnectRequest() { + ClientPacket newPacket; + + //send a disconnect request + newPacket.type = SerialPacketType::DISCONNECT_REQUEST; + newPacket.clientIndex = clientIndex; + + network.SendTo(Channels::SERVER, &newPacket); +} + +void World::SendAdminDisconnectForced() { + //TODO: empty +} + + +void World::SendAdminShutdownRequest() { + ClientPacket newPacket; + + //send a shutdown request + newPacket.type = SerialPacketType::ADMIN_SHUTDOWN_REQUEST; + newPacket.accountIndex = accountIndex; + + network.SendTo(Channels::SERVER, &newPacket); +} + +void World::hLogoutResponse(ClientPacket* const argPacket) { + if (localCharacter) { + characterMap.erase(characterIndex); + localCharacter = nullptr; + } + + accountIndex = -1; + characterIndex = -1; + + //reset the camera + camera.marginX = camera.marginY = 0; + + //because, why not? I guess... + SendDisconnectRequest(); +} + +void World::hDisconnectResponse(ClientPacket* const argPacket) { + hLogoutResponse(argPacket);//shortcut + SetNextScene(SceneList::DISCONNECTEDSCREEN); + ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have successfully logged out"; +} + +void World::hAdminDisconnectForced(ClientPacket* const argPacket) { + hDisconnectResponse(argPacket);//shortcut + SetNextScene(SceneList::DISCONNECTEDSCREEN); + ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server"; +} + diff --git a/client/gameplay_scenes/in_world_scene.cpp b/client/gameplay_scenes/world_logic.cpp similarity index 62% rename from client/gameplay_scenes/in_world_scene.cpp rename to client/gameplay_scenes/world_logic.cpp index 44004ea..509d570 100644 --- a/client/gameplay_scenes/in_world_scene.cpp +++ b/client/gameplay_scenes/world_logic.cpp @@ -19,7 +19,7 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "in_world.hpp" +#include "world.hpp" #include "channels.hpp" @@ -34,7 +34,7 @@ //Public access members //------------------------- -InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): +World::World(int* const argClientIndex, int* const argAccountIndex): clientIndex(*argClientIndex), accountIndex(*argAccountIndex) { @@ -75,8 +75,8 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): memset(&newPacket, 0, MAX_PACKET_SIZE); newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; network.SendTo(Channels::SERVER, &newPacket); -// newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS; -// network.SendTo(Channels::SERVER, &newPacket); + newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS; + network.SendTo(Channels::SERVER, &newPacket); //set the camera's values camera.width = GetScreen()->w; @@ -86,7 +86,7 @@ InWorld::InWorld(int* const argClientIndex, int* const argAccountIndex): // } -InWorld::~InWorld() { +World::~World() { //unload the local data characterMap.clear(); monsterMap.clear(); @@ -96,11 +96,11 @@ InWorld::~InWorld() { //Frame loop //------------------------- -void InWorld::FrameStart() { +void World::FrameStart() { // } -void InWorld::Update() { +void World::Update() { //create and zero the buffer SerialPacket* packetBuffer = reinterpret_cast(new char[MAX_PACKET_SIZE]); memset(packetBuffer, 0, MAX_PACKET_SIZE); @@ -154,18 +154,18 @@ void InWorld::Update() { camera.y = localCharacter->GetOrigin().y - camera.marginY; } -void InWorld::FrameEnd() { +void World::FrameEnd() { // } -void InWorld::RenderFrame() { +void World::RenderFrame() { // SDL_FillRect(GetScreen(), 0, 0); Render(GetScreen()); SDL_Flip(GetScreen()); fps.Calculate(); } -void InWorld::Render(SDL_Surface* const screen) { +void World::Render(SDL_Surface* const screen) { //draw the map for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y); @@ -192,32 +192,32 @@ void InWorld::Render(SDL_Surface* const screen) { //Event handlers //------------------------- -void InWorld::QuitEvent() { +void World::QuitEvent() { //two-step logout SendDisconnectRequest(); SetNextScene(SceneList::QUIT); } -void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) { +void World::MouseMotion(SDL_MouseMotionEvent const& motion) { disconnectButton.MouseMotion(motion); shutDownButton.MouseMotion(motion); } -void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) { +void World::MouseButtonDown(SDL_MouseButtonEvent const& button) { disconnectButton.MouseButtonDown(button); shutDownButton.MouseButtonDown(button); } -void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) { +void World::MouseButtonUp(SDL_MouseButtonEvent const& button) { if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { SendLogoutRequest(); } if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER && button.button == SDL_BUTTON_LEFT) { - SendShutdownRequest(); + SendAdminShutdownRequest(); } } -void InWorld::KeyDown(SDL_KeyboardEvent const& key) { +void World::KeyDown(SDL_KeyboardEvent const& key) { //hotkeys switch(key.keysym.sym) { case SDLK_ESCAPE: @@ -258,7 +258,7 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) { SendLocalCharacterMovement(); } -void InWorld::KeyUp(SDL_KeyboardEvent const& key) { +void World::KeyUp(SDL_KeyboardEvent const& key) { //character movement if (!localCharacter) { return; @@ -302,4 +302,117 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) { localCharacter->SetMotion(motion); localCharacter->CorrectSprite(); SendLocalCharacterMovement(); +} + +//------------------------- +//Direct incoming traffic +//------------------------- + +void World::HandlePacket(SerialPacket* const argPacket) { + switch(argPacket->type) { + //heartbeat system + case SerialPacketType::PING: + hPing(static_cast(argPacket)); + break; + case SerialPacketType::PONG: + hPong(static_cast(argPacket)); + break; + + //game server connections + case SerialPacketType::LOGOUT_RESPONSE: + hLogoutResponse(static_cast(argPacket)); + break; + case SerialPacketType::DISCONNECT_RESPONSE: + hDisconnectResponse(static_cast(argPacket)); + break; + case SerialPacketType::ADMIN_DISCONNECT_FORCED: + hAdminDisconnectForced(static_cast(argPacket)); + break; + + //map management + case SerialPacketType::REGION_CONTENT: + hRegionContent(static_cast(argPacket)); + break; + + //character management + case SerialPacketType::CHARACTER_CREATE: + hCharacterCreate(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_DELETE: + hCharacterDelete(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_EXISTS: + hQueryCharacterExists(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_STATS: + hQueryCharacterStats(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_CHARACTER_LOCATION: + hQueryCharacterLocation(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_MOVEMENT: + hCharacterMovement(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_ATTACK: + hCharacterAttack(static_cast(argPacket)); + break; + case SerialPacketType::CHARACTER_DAMAGE: + hCharacterDamage(static_cast(argPacket)); + break; + + //monster management + case SerialPacketType::MONSTER_CREATE: + hMonsterCreate(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_DELETE: + hMonsterDelete(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_EXISTS: + hQueryMonsterExists(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_STATS: + hQueryMonsterStats(static_cast(argPacket)); + break; + case SerialPacketType::QUERY_MONSTER_LOCATION: + hQueryMonsterLocation(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_MOVEMENT: + hMonsterMovement(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_ATTACK: + hMonsterAttack(static_cast(argPacket)); + break; + case SerialPacketType::MONSTER_DAMAGE: + hMonsterDamage(static_cast(argPacket)); + break; + + //chat + case SerialPacketType::TEXT_BROADCAST: + hTextBroadcast(static_cast(argPacket)); + break; + case SerialPacketType::TEXT_SPEECH: + hTextSpeech(static_cast(argPacket)); + break; + case SerialPacketType::TEXT_WHISPER: + hTextWhisper(static_cast(argPacket)); + break; + + //general rejection messages + case SerialPacketType::REGION_REJECTION: + case SerialPacketType::CHARACTER_REJECTION: + case SerialPacketType::QUERY_REJECTION: + throw(terminal_error(static_cast(argPacket)->text)); + break; + case SerialPacketType::SHUTDOWN_REJECTION: + throw(std::runtime_error(static_cast(argPacket)->text)); + break; + + //errors + default: { + std::ostringstream msg; + msg << "Unknown SerialPacketType encountered in World: " << static_cast(argPacket->type); + throw(std::runtime_error(msg.str())); + } + break; + } } \ No newline at end of file diff --git a/client/gameplay_scenes/world_map.cpp b/client/gameplay_scenes/world_map.cpp new file mode 100644 index 0000000..592c8e9 --- /dev/null +++ b/client/gameplay_scenes/world_map.cpp @@ -0,0 +1,79 @@ +/* Copyright: (c) Kayne Ruse 2013-2015 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "world.hpp" + +#include "channels.hpp" + +//------------------------- +//map management +//------------------------- + +void World::SendRegionRequest(int roomIndex, int x, int y) { + RegionPacket packet; + + //pack the region's data + packet.type = SerialPacketType::REGION_REQUEST; + packet.roomIndex = roomIndex; + packet.x = x; + packet.y = y; + + network.SendTo(Channels::SERVER, &packet); +} + +void World::hRegionContent(RegionPacket* const argPacket) { + //replace existing regions + regionPager.UnloadIf([&](Region const& region) -> bool { + return region.GetX() == argPacket->x && region.GetY() == argPacket->y; + }); + regionPager.PushRegion(argPacket->region); + + //clean up after the serial code + delete argPacket->region; + argPacket->region = nullptr; +} + +void World::UpdateMap() { + if (roomIndex == -1) { + return; + } + + //these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1) + int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH; + int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH; + + int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT; + int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT; + + //prune distant regions + regionPager.GetContainer()->remove_if([&](Region const& region) -> bool { + return region.GetX() < xStart || region.GetX() > xEnd || region.GetY() < yStart || region.GetY() > yEnd; + }); + + //request empty regions within this zone + for (int i = xStart; i <= xEnd; i += REGION_WIDTH) { + for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) { + if (!regionPager.FindRegion(i, j)) { + SendRegionRequest(roomIndex, i, j); + } + } + } +} \ No newline at end of file diff --git a/client/gameplay_scenes/in_world_monsters.cpp b/client/gameplay_scenes/world_monsters.cpp similarity index 84% rename from client/gameplay_scenes/in_world_monsters.cpp rename to client/gameplay_scenes/world_monsters.cpp index c9f3a45..9b8acda 100644 --- a/client/gameplay_scenes/in_world_monsters.cpp +++ b/client/gameplay_scenes/world_monsters.cpp @@ -19,7 +19,7 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#include "in_world.hpp" +#include "world.hpp" #include "channels.hpp" @@ -31,7 +31,7 @@ //monster management //------------------------- -void InWorld::HandleMonsterCreate(MonsterPacket* const argPacket) { +void World::hMonsterCreate(MonsterPacket* const argPacket) { //check for logic errors if (monsterMap.find(argPacket->monsterIndex) != monsterMap.end()) { std::ostringstream msg; @@ -64,7 +64,7 @@ void InWorld::HandleMonsterCreate(MonsterPacket* const argPacket) { std::cout << "Monster Create, total: " << monsterMap.size() << std::endl; } -void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { +void World::hMonsterDelete(MonsterPacket* const argPacket) { //ignore if this monster doesn't exist std::map::iterator monsterIt = monsterMap.find(argPacket->monsterIndex); if (monsterIt == monsterMap.end()) { @@ -78,7 +78,7 @@ void InWorld::HandleMonsterDelete(MonsterPacket* const argPacket) { std::cout << "Monster Delete, total: " << monsterMap.size() << std::endl; } -void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { +void World::hQueryMonsterExists(MonsterPacket* const argPacket) { //ignore monsters in a different room (sub-optimal) if (argPacket->roomIndex != roomIndex) { return; @@ -98,7 +98,15 @@ void InWorld::HandleMonsterQueryExists(MonsterPacket* const argPacket) { std::cout << "Monster Query, total: " << monsterMap.size() << std::endl; } -void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { +void World::hQueryMonsterStats(MonsterPacket* const argPacket) { + //TODO: empty +} + +void World::hQueryMonsterLocation(MonsterPacket* const argPacket) { + //TODO: empty +} + +void World::hMonsterMovement(MonsterPacket* const argPacket) { //ignore if this monster doesn't exist std::map::iterator monsterIt = monsterMap.find(argPacket->monsterIndex); if (monsterIt == monsterMap.end()) { @@ -109,6 +117,10 @@ void InWorld::HandleMonsterMovement(MonsterPacket* const argPacket) { monsterIt->second.SetOrigin(argPacket->motion); } -void InWorld::HandleMonsterAttack(MonsterPacket* const argPacket) { +void World::hMonsterAttack(MonsterPacket* const argPacket) { //TODO: (1) HandleMonsterAttack +} + +void World::hMonsterDamage(MonsterPacket* const argPacket) { + //TODO: (1) empty } \ No newline at end of file diff --git a/client/menu_scenes/lobby_menu.cpp b/client/menu_scenes/lobby_menu.cpp index 95704a0..f9997b7 100644 --- a/client/menu_scenes/lobby_menu.cpp +++ b/client/menu_scenes/lobby_menu.cpp @@ -248,7 +248,7 @@ void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) { throw(std::runtime_error("Client index invalid during login")); } accountIndex = argPacket->accountIndex; - SetNextScene(SceneList::INWORLD); + SetNextScene(SceneList::WORLD); } void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) { diff --git a/client/menu_scenes/main_menu.cpp b/client/menu_scenes/main_menu.cpp index cd62757..53bda74 100644 --- a/client/menu_scenes/main_menu.cpp +++ b/client/menu_scenes/main_menu.cpp @@ -125,5 +125,9 @@ void MainMenu::KeyDown(SDL_KeyboardEvent const& key) { } void MainMenu::KeyUp(SDL_KeyboardEvent const& key) { - // + switch(key.keysym.sym) { + case SDLK_ESCAPE: + QuitEvent(); + break; + } } diff --git a/client/scene_list.hpp b/client/scene_list.hpp index 475e5bb..2db5145 100644 --- a/client/scene_list.hpp +++ b/client/scene_list.hpp @@ -33,7 +33,7 @@ enum class SceneList { MAINMENU, OPTIONSMENU, LOBBYMENU, - INWORLD, + WORLD, DISCONNECTEDSCREEN, }; diff --git a/common/network/serial_packet_type.hpp b/common/network/serial_packet_type.hpp index cd798ab..d538c24 100644 --- a/common/network/serial_packet_type.hpp +++ b/common/network/serial_packet_type.hpp @@ -141,6 +141,7 @@ enum class SerialPacketType { CHARACTER_REJECTION, MONSTER_REJECTION, SHUTDOWN_REJECTION, + QUERY_REJECTION, //------------------------- //not used diff --git a/common/network/serial_utility.cpp b/common/network/serial_utility.cpp index 7159b10..25a3dfc 100644 --- a/common/network/serial_utility.cpp +++ b/common/network/serial_utility.cpp @@ -100,6 +100,7 @@ void serializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::CHARACTER_REJECTION: case SerialPacketType::MONSTER_REJECTION: case SerialPacketType::SHUTDOWN_REJECTION: + case SerialPacketType::QUERY_REJECTION: serializeText(buffer, static_cast(packet)); break; } @@ -164,6 +165,7 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) { case SerialPacketType::CHARACTER_REJECTION: case SerialPacketType::MONSTER_REJECTION: case SerialPacketType::SHUTDOWN_REJECTION: + case SerialPacketType::QUERY_REJECTION: deserializeText(buffer, static_cast(packet)); break; } diff --git a/server/server_logic.cpp b/server/server_logic.cpp index 83ee0b6..c64525f 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -213,7 +213,7 @@ void ServerApplication::Quit() { } //------------------------- -//direct incoming traffic +//handle incoming traffic //------------------------- void ServerApplication::HandlePacket(SerialPacket* const argPacket) { From 87af4f1a1ede52e8a87d4531f94edeca4a0b9f44 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 14 Feb 2015 23:54:18 +1100 Subject: [PATCH 21/21] Comment tweaks, updated network version --- client/entities/base_monster.cpp | 2 +- client/gameplay_scenes/world.hpp | 2 +- client/gameplay_scenes/world_characters.cpp | 8 ++++---- client/gameplay_scenes/world_chat.cpp | 6 +++--- client/gameplay_scenes/world_connections.cpp | 2 +- client/gameplay_scenes/world_logic.cpp | 4 ++-- client/gameplay_scenes/world_monsters.cpp | 8 ++++---- client/menu_scenes/lobby_menu.cpp | 8 ++++---- client/menu_scenes/main_menu.cpp | 2 +- common/network/serial_packet.hpp | 2 +- server/server_character_methods.cpp | 6 +++--- server/server_logic.cpp | 3 ++- server/server_methods.cpp | 6 +++++- 13 files changed, 32 insertions(+), 27 deletions(-) diff --git a/client/entities/base_monster.cpp b/client/entities/base_monster.cpp index 2d979e0..c268021 100644 --- a/client/entities/base_monster.cpp +++ b/client/entities/base_monster.cpp @@ -24,7 +24,7 @@ #include "config_utility.hpp" void BaseMonster::CorrectSprite() { - //TODO: (1) CorrectSprite + //TODO: (9) empty } std::string BaseMonster::SetHandle(std::string s) { diff --git a/client/gameplay_scenes/world.hpp b/client/gameplay_scenes/world.hpp index cc2135a..bb57f75 100644 --- a/client/gameplay_scenes/world.hpp +++ b/client/gameplay_scenes/world.hpp @@ -156,7 +156,7 @@ protected: LocalCharacter* localCharacter = nullptr; //heartbeat - //TODO: (9) Heartbeat needs it's own utility + //TODO: (2) Heartbeat needs it's own utility typedef std::chrono::steady_clock Clock; Clock::time_point lastBeat = Clock::now(); int attemptedBeats = 0; diff --git a/client/gameplay_scenes/world_characters.cpp b/client/gameplay_scenes/world_characters.cpp index 8512e76..4091824 100644 --- a/client/gameplay_scenes/world_characters.cpp +++ b/client/gameplay_scenes/world_characters.cpp @@ -128,11 +128,11 @@ void World::hQueryCharacterExists(CharacterPacket* const argPacket) { } void World::hQueryCharacterStats(CharacterPacket* const argPacket) { - //TODO: empty + //TODO: (9) empty } void World::hQueryCharacterLocation(CharacterPacket* const argPacket) { - //TODO: empty + //TODO: (9) empty } void World::hCharacterMovement(CharacterPacket* const argPacket) { @@ -152,11 +152,11 @@ void World::hCharacterMovement(CharacterPacket* const argPacket) { } void World::hCharacterAttack(CharacterPacket* const argPacket) { - //TODO: (1) attack animation + //TODO: (9) empty } void World::hCharacterDamage(CharacterPacket* const argPacket) { - //TODO: (1) attack animation + //TODO: (9) empty } //------------------------- diff --git a/client/gameplay_scenes/world_chat.cpp b/client/gameplay_scenes/world_chat.cpp index 9386478..3a29d21 100644 --- a/client/gameplay_scenes/world_chat.cpp +++ b/client/gameplay_scenes/world_chat.cpp @@ -26,14 +26,14 @@ //------------------------- void World::hTextBroadcast(TextPacket* const argPacket) { - //TODO: (1) empty + //TODO: (9) empty } void World::hTextSpeech(TextPacket* const argPacket) { - //TODO: (1) empty + //TODO: (9) empty } void World::hTextWhisper(TextPacket* const argPacket) { - //TODO: (1) empty + //TODO: (9) empty } diff --git a/client/gameplay_scenes/world_connections.cpp b/client/gameplay_scenes/world_connections.cpp index c20c101..7ace62d 100644 --- a/client/gameplay_scenes/world_connections.cpp +++ b/client/gameplay_scenes/world_connections.cpp @@ -91,7 +91,7 @@ void World::SendDisconnectRequest() { } void World::SendAdminDisconnectForced() { - //TODO: empty + //TODO: (9) empty } diff --git a/client/gameplay_scenes/world_logic.cpp b/client/gameplay_scenes/world_logic.cpp index 509d570..dcb74d0 100644 --- a/client/gameplay_scenes/world_logic.cpp +++ b/client/gameplay_scenes/world_logic.cpp @@ -60,7 +60,7 @@ World::World(int* const argClientIndex, int* const argAccountIndex): shutDownButton.SetText("Shut Down"); //load the tilesheet - //TODO: (9) Tile size and tile sheet should be loaded elsewhere + //TODO: (1) Tile size and tile sheet should be loaded elsewhere tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32); //Send the character data @@ -221,7 +221,7 @@ void World::KeyDown(SDL_KeyboardEvent const& key) { //hotkeys switch(key.keysym.sym) { case SDLK_ESCAPE: - //TODO: (9) the escape key should actually control menus and stuff + //TODO: (1) the escape key should actually control menus and stuff SendLogoutRequest(); return; } diff --git a/client/gameplay_scenes/world_monsters.cpp b/client/gameplay_scenes/world_monsters.cpp index 9b8acda..8891fad 100644 --- a/client/gameplay_scenes/world_monsters.cpp +++ b/client/gameplay_scenes/world_monsters.cpp @@ -99,11 +99,11 @@ void World::hQueryMonsterExists(MonsterPacket* const argPacket) { } void World::hQueryMonsterStats(MonsterPacket* const argPacket) { - //TODO: empty + //TODO: (9) empty } void World::hQueryMonsterLocation(MonsterPacket* const argPacket) { - //TODO: empty + //TODO: (9) empty } void World::hMonsterMovement(MonsterPacket* const argPacket) { @@ -118,9 +118,9 @@ void World::hMonsterMovement(MonsterPacket* const argPacket) { } void World::hMonsterAttack(MonsterPacket* const argPacket) { - //TODO: (1) HandleMonsterAttack + //TODO: (9) empty } void World::hMonsterDamage(MonsterPacket* const argPacket) { - //TODO: (1) empty + //TODO: (9) empty } \ No newline at end of file diff --git a/client/menu_scenes/lobby_menu.cpp b/client/menu_scenes/lobby_menu.cpp index f9997b7..8ebc361 100644 --- a/client/menu_scenes/lobby_menu.cpp +++ b/client/menu_scenes/lobby_menu.cpp @@ -100,14 +100,14 @@ void LobbyMenu::FrameEnd() { } void LobbyMenu::Render(SDL_Surface* const screen) { - //TODO: (9) I need a proper UI system for the entire client and the editor + //TODO: (2) I need a proper UI system for the entire client and the editor //UI search.DrawTo(screen); join.DrawTo(screen); back.DrawTo(screen); - //TODO: (9) draw headers for the server list + //TODO: (1) draw headers for the server list for (int i = 0; i < serverInfo.size(); i++) { //draw the selected server's highlight if (selection == &serverInfo[i]) { @@ -252,11 +252,11 @@ void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) { } void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) { - //TODO: (9) Better output for join rejection + //TODO: (9) empty } void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) { - //TODO: (9) Better output for login rejection + //TODO: (9) empty } //------------------------- diff --git a/client/menu_scenes/main_menu.cpp b/client/menu_scenes/main_menu.cpp index 53bda74..e6735d1 100644 --- a/client/menu_scenes/main_menu.cpp +++ b/client/menu_scenes/main_menu.cpp @@ -108,7 +108,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { } void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { - //TODO: (9) Buttons should only register as "selected" when the left button is used + //TODO: (2) Buttons should only register as "selected" when the left button is used if (startButton.MouseButtonUp(button) == Button::State::HOVER) { SetNextScene(SceneList::LOBBYMENU); } diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 0c07cae..2075c75 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -34,7 +34,7 @@ typedef SerialPacketBase SerialPacket; //DOCS: NETWORK_VERSION is used to discern compatible servers and clients -constexpr int NETWORK_VERSION = 20150213; +constexpr int NETWORK_VERSION = 20150214; union MaxPacket { CharacterPacket a; diff --git a/server/server_character_methods.cpp b/server/server_character_methods.cpp index 5c76f83..38127e1 100644 --- a/server/server_character_methods.cpp +++ b/server/server_character_methods.cpp @@ -175,7 +175,7 @@ void ServerApplication::hCharacterUnload(CharacterPacket* const argPacket) { //character movement //------------------------- -//TODO: (9) Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments +//TODO: (2) Could replace this verbosity with a "verify" method, taking a client, account and character ptr as arguments void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { //get the specified objects @@ -197,7 +197,7 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { //check if allowed if (characterData->GetOwner() != argPacket->accountIndex && !accountData->GetModerator() && !accountData->GetAdministrator()) { - //TODO: (9) send to the client? + //TODO: (2) send to the client? std::cerr << "Failed to set character motion due to lack of permissions targeting uid(" << argPacket->characterIndex << ")" << std::endl; return; } @@ -235,7 +235,7 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) { } void ServerApplication::hCharacterAttack(CharacterPacket* const argPacket) { - //TODO: (9) bounce graphical attack data + //TODO: (9) empty } void ServerApplication::hCharacterDamage(CharacterPacket* const argPacket) { diff --git a/server/server_logic.cpp b/server/server_logic.cpp index c64525f..78d5114 100644 --- a/server/server_logic.cpp +++ b/server/server_logic.cpp @@ -194,7 +194,8 @@ void ServerApplication::Proc() { void ServerApplication::Quit() { std::cout << "Shutting down" << std::endl; - //TODO: (9) save the server state + //save the server state + SaveServerState(); //close the managers accountMgr.UnloadAll(); diff --git a/server/server_methods.cpp b/server/server_methods.cpp index 0b55219..d440153 100644 --- a/server/server_methods.cpp +++ b/server/server_methods.cpp @@ -30,7 +30,7 @@ //------------------------- void ServerApplication::hAdminDisconnectForced(ClientPacket* const argPacket) { - //TODO: (9) boot players + //TODO: (9) empty } void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { @@ -84,6 +84,10 @@ void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { std::cout << "Shutdown signal accepted" << std::endl; } +void ServerApplication::SaveServerState() { + //TODO: (9) empty +} + //------------------------- //full unload methods //-------------------------