Fleshed out ClientManager

* Fleshed out the ClientManager internals
* Folded some ServerApplication methods into ClientManager
* Removed Manager references from ServerApplication
* Corrected server_methods.cpp (compiles)
This commit is contained in:
Kayne Ruse
2014-11-08 16:33:27 +11:00
parent 74234684af
commit f7ba34dcec
8 changed files with 117 additions and 98 deletions
+63 -20
View File
@@ -21,46 +21,89 @@
*/ */
#include "client_manager.hpp" #include "client_manager.hpp"
#include "udp_network_utility.hpp"
#include <chrono>
int ClientManager::CheckConnections() {
for (auto& it : elementMap) {
//3 seconds between beats
if (ClientData::Clock::now() - it.second.GetLastBeat() > std::chrono::seconds(3)) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
UDPNetworkUtility::GetSingleton().SendTo(it.second.GetAddress(), &newPacket);
it.second.IncrementAttempts();
}
}
for (auto& it : elementMap) {
if (it.second.GetAttempts() > 2) {
int ret = it.first;
elementMap.erase(it.first);
return ret;
}
}
return -1;
}
void ClientManager::HandlePong(ServerPacket* const argPacket) {
//find and update the specified client
for (auto& it : elementMap) {
if (it.second.GetAddress().host == argPacket->srcAddress.host &&
it.second.GetAddress().port == argPacket->srcAddress.port
) {
it.second.ResetAttempts();
return;
}
}
}
int ClientManager::Create(IPaddress add) { int ClientManager::Create(IPaddress add) {
//TODO ClientData& client = elementMap[counter];
} client.SetAddress(add);
return counter++;
int ClientManager::Load(IPaddress add) {
//TODO
}
int ClientManager::Save(int uid) {
//TODO
} }
void ClientManager::Unload(int uid) { void ClientManager::Unload(int uid) {
//TODO elementMap.erase(uid);
}
void ClientManager::Delete(int uid) {
//TODO
} }
void ClientManager::UnloadAll() { void ClientManager::UnloadAll() {
//TODO elementMap.clear();
} }
void ClientManager::UnloadIf(std::function<bool(std::pair<const int, ClientData>)> fn) { void ClientManager::UnloadIf(std::function<bool(std::pair<const int, ClientData>)> fn) {
//TODO std::map<int, ClientData>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
it = elementMap.erase(it);
//TODO: ? disconnect, unload characters, notify other clients
}
else {
++it;
}
}
} }
ClientData* ClientManager::Get(int uid) { ClientData* ClientManager::Get(int uid) {
//TODO std::map<int, ClientData>::iterator it = elementMap.find(uid);
if (it == elementMap.end()) {
return nullptr;
}
return &it->second;
} }
int ClientManager::GetLoadedCount() { int ClientManager::GetLoadedCount() {
//TODO return elementMap.size();
} }
int ClientManager::GetTotalCount() { int ClientManager::GetTotalCount() {
//TODO return elementMap.size();
} }
std::map<int, ClientData>* ClientManager::GetContainer() { std::map<int, ClientData>* ClientManager::GetContainer() {
//TODO return &elementMap;
} }
+12 -5
View File
@@ -24,6 +24,7 @@
#include "client_data.hpp" #include "client_data.hpp"
#include "manager_interface.hpp" #include "manager_interface.hpp"
#include "server_packet.hpp"
#include "singleton.hpp" #include "singleton.hpp"
#include "SDL/SDL_net.h" #include "SDL/SDL_net.h"
@@ -31,16 +32,17 @@
#include <functional> #include <functional>
class ClientManager: class ClientManager:
Singleton<ClientManager>, public Singleton<ClientManager>,
ManagerInterface<ClientData, IPaddress> public ManagerInterface<ClientData, IPaddress>
{ {
public: public:
//methods
int CheckConnections();
void HandlePong(ServerPacket* const argPacket);
//common public methods //common public methods
int Create(IPaddress) override; int Create(IPaddress) override;
int Load(IPaddress) override;
int Save(int uid) override;
void Unload(int uid) override; void Unload(int uid) override;
void Delete(int uid) override;
void UnloadAll() override; void UnloadAll() override;
void UnloadIf(std::function<bool(std::pair<const int, ClientData>)> fn) override; void UnloadIf(std::function<bool(std::pair<const int, ClientData>)> fn) override;
@@ -57,6 +59,11 @@ private:
ClientManager() = default; ClientManager() = default;
~ClientManager() = default; ~ClientManager() = default;
//EMPTY
int Load(IPaddress) override { return -1; }
int Save(int uid) override { return -1; }
void Delete(int uid) override { return; }
int counter = 0; int counter = 0;
}; };
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../server_utilities ../../common/utilities INCLUDES+=. ../server_utilities ../../common/network ../../common/network/packet_types ../../common/utilities
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+2 -2
View File
@@ -31,8 +31,8 @@
#include <string> #include <string>
class DoorManager: class DoorManager:
Singleton<DoorManager>, public Singleton<DoorManager>,
ManagerInterface<DoorData, std::string, Vector2> public ManagerInterface<DoorData, std::string, Vector2>
{ {
public: public:
//common public methods //common public methods
+2 -2
View File
@@ -38,8 +38,8 @@
#include <string> #include <string>
class MonsterManager: class MonsterManager:
Singleton<MonsterManager>, public Singleton<MonsterManager>,
ManagerInterface<MonsterData, std::string> public ManagerInterface<MonsterData, std::string>
{ {
public: public:
//common public methods //common public methods
-11
View File
@@ -22,16 +22,8 @@
#ifndef SERVERAPPLICATION_HPP_ #ifndef SERVERAPPLICATION_HPP_
#define SERVERAPPLICATION_HPP_ #define SERVERAPPLICATION_HPP_
//server specific stuff, mostly managers
#include "client_data.hpp"
#include "account_manager.hpp"
#include "character_manager.hpp"
#include "room_manager.hpp"
//common utilities //common utilities
#include "udp_network_utility.hpp"
#include "serial_packet.hpp" #include "serial_packet.hpp"
#include "config_utility.hpp"
#include "singleton.hpp" #include "singleton.hpp"
//APIs //APIs
@@ -67,8 +59,6 @@ private:
void HandlePacket(SerialPacket* const); void HandlePacket(SerialPacket* const);
//basic connections //basic connections
void HandlePing(ServerPacket* const);
void HandlePong(ServerPacket* const);
void HandleBroadcastRequest(ServerPacket* const); void HandleBroadcastRequest(ServerPacket* const);
void HandleJoinRequest(ClientPacket* const); void HandleJoinRequest(ClientPacket* const);
void HandleDisconnect(ClientPacket* const); void HandleDisconnect(ClientPacket* const);
@@ -86,7 +76,6 @@ private:
void HandleSynchronize(ClientPacket* const); void HandleSynchronize(ClientPacket* const);
//utility methods //utility methods
void CheckClientConnections();
//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 CleanupLostConnection(int index); void CleanupLostConnection(int index);
void PumpPacket(SerialPacket* const); void PumpPacket(SerialPacket* const);
+37 -19
View File
@@ -21,10 +21,21 @@
*/ */
#include "server_application.hpp" #include "server_application.hpp"
//managers
#include "account_manager.hpp"
#include "character_manager.hpp"
#include "client_manager.hpp"
#include "room_manager.hpp"
//utilities
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
//utility functions //utility functions
#include "sql_tools.hpp" #include "sql_tools.hpp"
#include "utility.hpp" #include "utility.hpp"
//std & STL
#include <stdexcept> #include <stdexcept>
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
@@ -41,7 +52,8 @@ void ServerApplication::Init(int argc, char* argv[]) {
//NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed. //NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
std::cout << "Beginning " << argv[0] << std::endl; std::cout << "Beginning " << argv[0] << std::endl;
//load the prerequisites //load the config settings
ConfigUtility& config = ConfigUtility::GetSingleton();
config.Load("rsc/config.cfg", argc, argv); config.Load("rsc/config.cfg", argc, argv);
//------------------------- //-------------------------
@@ -58,7 +70,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
if (SDLNet_Init()) { if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net")); throw(std::runtime_error("Failed to initialize SDL_net"));
} }
network.Open(config.Int("server.port")); UDPNetworkUtility::GetSingleton().Open(config.Int("server.port"));
std::cout << "Initialized SDL_net" << std::endl; std::cout << "Initialized SDL_net" << std::endl;
//Init SQL //Init SQL
@@ -77,7 +89,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
std::cout << "Initialized lua" << std::endl; std::cout << "Initialized lua" << std::endl;
//append config["dir.scripts"] to the module path //prepend config["dir.scripts"] to the module path
if (config["dir.scripts"].size() > 0) { if (config["dir.scripts"].size() > 0) {
//get the original path //get the original path
lua_getglobal(luaState, "package"); lua_getglobal(luaState, "package");
@@ -100,10 +112,10 @@ void ServerApplication::Init(int argc, char* argv[]) {
//------------------------- //-------------------------
//set the hooks //set the hooks
accountMgr.SetDatabase(database); AccountManager::GetSingleton().SetDatabase(database);
characterMgr.SetDatabase(database); CharacterManager::GetSingleton().SetDatabase(database);
roomMgr.SetLuaState(luaState); RoomManager::GetSingleton().SetLuaState(luaState);
std::cout << "Internal managers initialized" << std::endl; std::cout << "Internal managers initialized" << std::endl;
@@ -164,14 +176,17 @@ void ServerApplication::Proc() {
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]); SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
while(running) { while(running) {
//suck in the waiting packets & process them //suck in the waiting packets & process them
while(network.Receive(packetBuffer)) { while(UDPNetworkUtility::GetSingleton().Receive(packetBuffer)) {
HandlePacket(packetBuffer); HandlePacket(packetBuffer);
} }
//update the internals //update the internals
//... //...
//Check connections //Check connections
CheckClientConnections(); int disconnected = ClientManager::GetSingleton().CheckConnections();
if (disconnected != -1) {
//TODO: clean up after this disconnection
}
//give the computer a break //give the computer a break
SDL_Delay(10); SDL_Delay(10);
@@ -183,17 +198,15 @@ void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl; std::cout << "Shutting down" << std::endl;
//close the managers //close the managers
clientMap.clear(); ClientManager::GetSingleton().UnloadAll();
accountMgr.UnloadAll(); AccountManager::GetSingleton().UnloadAll();
characterMgr.UnloadAll(); CharacterManager::GetSingleton().UnloadAll();
//TODO: unload combats RoomManager::GetSingleton().UnloadAll();
//TODO: unload enemies
roomMgr.UnloadAll();
//APIs //APIs
lua_close(luaState); lua_close(luaState);
sqlite3_close_v2(database); sqlite3_close_v2(database);
network.Close(); UDPNetworkUtility::GetSingleton().Close();
SDLNet_Quit(); SDLNet_Quit();
SDL_Quit(); SDL_Quit();
@@ -206,13 +219,18 @@ void ServerApplication::Quit() {
void ServerApplication::HandlePacket(SerialPacket* const argPacket) { void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) { switch(argPacket->type) {
//basic connections //heartbeat system
case SerialPacketType::PING: case SerialPacketType::PING: {
HandlePing(static_cast<ServerPacket*>(argPacket)); ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
UDPNetworkUtility::GetSingleton().SendTo(argPacket->srcAddress, &newPacket);
}
break; break;
case SerialPacketType::PONG: case SerialPacketType::PONG:
HandlePong(static_cast<ServerPacket*>(argPacket)); ClientManager::GetSingleton().HandlePong(static_cast<ServerPacket*>(argPacket));
break; break;
//connections
case SerialPacketType::BROADCAST_REQUEST: case SerialPacketType::BROADCAST_REQUEST:
HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket)); HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket));
break; break;
-38
View File
@@ -28,26 +28,6 @@
//basic connections //basic connections
//------------------------- //-------------------------
//SET: utility
void ServerApplication::HandlePing(ServerPacket* const argPacket) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
//SET: utility/manager
void ServerApplication::HandlePong(ServerPacket* const argPacket) {
//find and update the specified client
for (auto& it : clientMap) {
if (it.second.GetAddress().host == argPacket->srcAddress.host &&
it.second.GetAddress().port == argPacket->srcAddress.port
) {
it.second.ResetAttempts();
break;
}
}
}
//SET: utility //SET: utility
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) { void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
//send the server's data //send the server's data
@@ -293,24 +273,6 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//utility methods //utility methods
//------------------------- //-------------------------
//SET: utility/manager
void ServerApplication::CheckClientConnections() {
for (auto& it : clientMap) {
if (std::chrono::steady_clock::now() - it.second.GetLastBeat() > std::chrono::seconds(3)) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
network.SendTo(it.second.GetAddress(), &newPacket);
it.second.IncrementAttempts();
}
if (it.second.GetAttempts() > 2) {
CleanupLostConnection(it.first);
//all iterators are invalid, so we can't continue
break;
}
}
}
//SET: utility/manager //SET: utility/manager
void ServerApplication::CleanupLostConnection(int clientIndex) { void ServerApplication::CleanupLostConnection(int clientIndex) {
//NOTE: This assumes each player has only one account and character at a time //NOTE: This assumes each player has only one account and character at a time