The server is building, but still needs work

There is some missing character creation/unloading code, and there are a
few other issues highlighted by TODO tags, see below.

In general, 'mapIndex' has been renamed to 'roomIndex'. Multiple rooms
have not been fully implemented yet, but I'm working on it.

Other issues:

* FileFormat needs to be changed to MapLoader
* Server's character movement is still slaved to the clients

The client does not build.
This commit is contained in:
Kayne Ruse
2014-06-07 02:12:40 +10:00
parent cac273da5e
commit 63be0ee70d
10 changed files with 85 additions and 56 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ struct CharacterData {
std::string avatar; std::string avatar;
//world position //world position
int mapIndex = 0; int roomIndex = 0;
Vector2 origin = {0.0,0.0}; Vector2 origin = {0.0,0.0};
Vector2 motion = {0.0,0.0}; Vector2 motion = {0.0,0.0};
Vector2 bounds = {0.0,0.0}; Vector2 bounds = {0.0,0.0};
+2
View File
@@ -28,6 +28,8 @@
#include <string> #include <string>
//TODO: I'm unhappy with using this system, there needs to be a way to handle saving/loading better
class DummyFormat { class DummyFormat {
public: public:
void Load(Region** const, int x, int y); void Load(Region** const, int x, int y);
+3 -3
View File
@@ -22,9 +22,9 @@
#ifndef REGION_HPP_ #ifndef REGION_HPP_
#define REGION_HPP_ #define REGION_HPP_
#define REGION_WIDTH 20 constexpr int REGION_WIDTH = 20;
#define REGION_HEIGHT 20 constexpr int REGION_HEIGHT = 20;
#define REGION_DEPTH 3 constexpr int REGION_DEPTH = 3;
class Region { class Region {
public: public:
+2
View File
@@ -27,6 +27,8 @@
#include "region_pager.hpp" #include "region_pager.hpp"
//NOTE: When operating on a region, setTile() & getTile() *are not* zero indexed, but when operating on the entire map they *are* zero indexed. //NOTE: When operating on a region, setTile() & getTile() *are not* zero indexed, but when operating on the entire map they *are* zero indexed.
//TODO: enforce all possible parameter counts
//TODO: update the map API to handle multiple rooms
static int setTile(lua_State* L) { static int setTile(lua_State* L) {
if (lua_gettop(L) == 5) { if (lua_gettop(L) == 5) {
+1 -1
View File
@@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS Characters (
birth timestamp NOT NULL DEFAULT (datetime()), birth timestamp NOT NULL DEFAULT (datetime()),
--position --position
mapIndex INTEGER DEFAULT 0, roomIndex INTEGER DEFAULT 0,
originX INTEGER DEFAULT 0, originX INTEGER DEFAULT 0,
originY INTEGER DEFAULT 0, originY INTEGER DEFAULT 0,
+3 -3
View File
@@ -33,7 +33,7 @@ static const char* CREATE_CHARACTER = "INSERT INTO Characters (owner, handle, av
static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;"; static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;";
static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET " static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET "
"mapIndex = ?2," "roomIndex = ?2,"
"originX = ?3," "originX = ?3,"
"originY = ?4," "originY = ?4,"
"level = ?5," "level = ?5,"
@@ -148,7 +148,7 @@ int CharacterManager::LoadCharacter(int owner, std::string handle, std::string a
//Don't cache the birth //Don't cache the birth
//world origin //world origin
newChar.mapIndex = sqlite3_column_int(statement, 5); newChar.roomIndex = sqlite3_column_int(statement, 5);
newChar.origin.x = (double)sqlite3_column_int(statement, 6); newChar.origin.x = (double)sqlite3_column_int(statement, 6);
newChar.origin.y = (double)sqlite3_column_int(statement, 7); newChar.origin.y = (double)sqlite3_column_int(statement, 7);
@@ -208,7 +208,7 @@ int CharacterManager::SaveCharacter(int uid) {
//parameters //parameters
bool ret = false; bool ret = false;
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 2, character.mapIndex) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK;
+11 -5
View File
@@ -22,6 +22,11 @@
#ifndef ROOMDATA_HPP_ #ifndef ROOMDATA_HPP_
#define ROOMDATA_HPP_ #define ROOMDATA_HPP_
//map system
#include "map_allocator.hpp"
#include "map_file_format.hpp"
#include "region_pager.hpp"
struct RoomData { struct RoomData {
enum class RoomType { enum class RoomType {
OVERWORLD, OVERWORLD,
@@ -31,11 +36,12 @@ struct RoomData {
CAVES, CAVES,
}; };
/* TODO: more //members
* "multiple rooms system" using this structure RegionPager<LuaAllocator, LuaFormat> pager;
* Pager RoomType type;
* collision map
*/ //TODO: collision map
//TODO: NPCs?
}; };
#endif #endif
+1
View File
@@ -35,6 +35,7 @@ public:
//public access methods //public access methods
//TODO //TODO
//TODO: setup the pagers and functors of each room object
//accessors and mutators //accessors and mutators
RoomData* GetRoom(int uid); RoomData* GetRoom(int uid);
+57 -34
View File
@@ -174,14 +174,14 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
//character management //character management
case SerialPacketType::CHARACTER_NEW: case SerialPacketType::CHARACTER_NEW:
HandleCharacterNew(dynamic_cast<SerialPacket*>(argPacket)); HandleCharacterNew(dynamic_cast<CharacterPacket*>(argPacket));
break; break;
case SerialPacketType::CHARACTER_DELETE: case SerialPacketType::CHARACTER_DELETE:
HandleCharacterDelete(dynamic_cast<SerialPacket*>(argPacket)); HandleCharacterDelete(dynamic_cast<CharacterPacket*>(argPacket));
break; break;
case SerialPacketType::CHARACTER_UPDATE: case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST: //TODO: ? case SerialPacketType::CHARACTER_STATS_REQUEST: //TODO: ?
HandleCharacterUpdate(dynamic_cast<SerialPacket*>(argPacket)); HandleCharacterUpdate(dynamic_cast<CharacterPacket*>(argPacket));
break; break;
//enemy management //enemy management
@@ -189,7 +189,7 @@ void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
//mismanagement //mismanagement
case SerialPacketType::SYNCHRONIZE: case SerialPacketType::SYNCHRONIZE:
HandleSynchronize(dynamic_cast<SerialPacket*>(argPacket)); HandleSynchronize(dynamic_cast<ClientPacket*>(argPacket));
break; break;
//handle errors //handle errors
@@ -296,7 +296,7 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
newPacket.x = argPacket->x; newPacket.x = argPacket->x;
newPacket.y = argPacket->y; newPacket.y = argPacket->y;
newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->GetPager()->GetRegion(argPacket->x, argPacket->y); newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->pager.GetRegion(argPacket->x, argPacket->y);
//send the content //send the content
network.SendTo(&argPacket->srcAddress, dynamic_cast<SerialPacket*>(argPacket)); network.SendTo(&argPacket->srcAddress, dynamic_cast<SerialPacket*>(argPacket));
@@ -312,25 +312,46 @@ void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
//Character Management //Character Management
//------------------------- //-------------------------
void ServerApplication::HandleCharacterNew(SerialPacket) { void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
//TODO: fill this //TODO: fill this
} }
void ServerApplication::HandleCharacterDelete(SerialPacket) { void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) {
//TODO: fill this //TODO: fill this
} }
void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) {
//TODO: this should be moved elsewhere CharacterData* character = characterMgr.GetCharacter(argPacket->characterIndex);
if (characterMap.find(packet.characterInfo.characterIndex) == characterMap.end()) {
throw(std::runtime_error("Cannot update a non-existant character")); //make a new character if this one doesn't exist
if (!character) {
//this isn't normal
std::cerr << "Warning: HandleCharacterUpdate() is passing to HandleCharacterNew()" << std::endl;
HandleCharacterNew(argPacket);
return;
} }
//TODO: the server needs it's own movement system too /* TODO: rewrite this design flaw, read more
characterMap[packet.characterInfo.characterIndex].origin = packet.characterInfo.origin; * Slaving the client to the server here is a terrible idea, instead there
characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion; * needs to be a utility function to update and send the server-side character
* to the clients.
*
* Other things to consider include functionality to reequip the character,
* apply status effects and to change the stats as well. These should all be
* handled server-side.
*/
character->roomIndex = argPacket->roomIndex;
character->origin = argPacket->origin;
character->motion = argPacket->motion;
PumpPacket(packet); character->stats = argPacket->stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
PumpPacket(argPacket);
} }
//------------------------- //-------------------------
@@ -343,26 +364,29 @@ void ServerApplication::HandleCharacterUpdate(SerialPacket packet) {
//mismanagement //mismanagement
//------------------------- //-------------------------
void ServerApplication::HandleSynchronize(SerialPacket packet) { void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//TODO: compensate for large distances //TODO: compensate for large distances
//TODO: I quite dislike this function
//send all the server's data to this client //send all the server's data to this client
SerialPacket newPacket; CharacterPacket characterPacket;
//characters //characters
newPacket.meta.type = SerialPacket::Type::CHARACTER_UPDATE; characterPacket.type = SerialPacketType::CHARACTER_UPDATE;
for (auto& it : characterMap) { for (auto& it : *characterMgr.GetContainer()) {
//TODO: update this for the expanded CharacterData structure //TODO: update this for the expanded CharacterData structure
newPacket.characterInfo.characterIndex = it.first; characterPacket.characterIndex = it.first;
snprintf(newPacket.characterInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); snprintf(characterPacket.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
snprintf(newPacket.characterInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); snprintf(characterPacket.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
newPacket.characterInfo.mapIndex = it.second.mapIndex; characterPacket.roomIndex = it.second.roomIndex;
newPacket.characterInfo.origin = it.second.origin; characterPacket.origin = it.second.origin;
newPacket.characterInfo.motion = it.second.motion; characterPacket.motion = it.second.motion;
newPacket.characterInfo.stats = it.second.stats; characterPacket.stats = it.second.stats;
network.SendTo(&clientMap[packet.clientInfo.clientIndex].address, &newPacket); network.SendTo(&clientMap[argPacket->clientIndex].address, dynamic_cast<SerialPacket*>(&characterPacket));
} }
//TODO: more
} }
//------------------------- //-------------------------
@@ -371,17 +395,16 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) {
//TODO: a function that only sends to characters in a certain proximity //TODO: a function that only sends to characters in a certain proximity
void ServerApplication::PumpPacket(SerialPacket packet) { void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
//NOTE: I don't really like this, but it'll do for now
for (auto& it : clientMap) { for (auto& it : clientMap) {
network.SendTo(&it.second.address, &packet); network.SendTo(&it.second.address, argPacket);
} }
} }
void ServerApplication::PumpCharacterUnload(int uid) { void ServerApplication::PumpCharacterUnload(int uid) {
//delete the client-side character(s) //delete the client-side character(s)
SerialPacket delPacket; CharacterPacket newPacket;
delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE; newPacket.type = SerialPacketType::CHARACTER_DELETE;
delPacket.characterInfo.characterIndex = uid; newPacket.characterIndex = uid;
PumpPacket(delPacket); PumpPacket(dynamic_cast<SerialPacket*>(&newPacket));
} }
+4 -9
View File
@@ -30,11 +30,6 @@
#include "enemy_manager.hpp" #include "enemy_manager.hpp"
#include "room_manager.hpp" #include "room_manager.hpp"
//maps
#include "map_allocator.hpp"
#include "map_file_format.hpp"
#include "region_pager.hpp"
//common utilities //common utilities
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
#include "config_utility.hpp" #include "config_utility.hpp"
@@ -76,15 +71,15 @@ private:
//TODO: combat management //TODO: combat management
//character management //character management
void HandleCharacterNew(SerialPacket* const); void HandleCharacterNew(CharacterPacket* const);
void HandleCharacterDelete(SerialPacket* const); void HandleCharacterDelete(CharacterPacket* const);
void HandleCharacterUpdate(SerialPacket* const); void HandleCharacterUpdate(CharacterPacket* const);
//enemy management //enemy management
//TODO: enemy management //TODO: enemy management
//mismanagement //mismanagement
void HandleSynchronize(SerialPacket* const); void HandleSynchronize(ClientPacket* const);
//utility methods //utility methods
//TODO: a function that only sends to characters in a certain proximity //TODO: a function that only sends to characters in a certain proximity