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 "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) {
//TODO
}
int ClientManager::Load(IPaddress add) {
//TODO
}
int ClientManager::Save(int uid) {
//TODO
ClientData& client = elementMap[counter];
client.SetAddress(add);
return counter++;
}
void ClientManager::Unload(int uid) {
//TODO
}
void ClientManager::Delete(int uid) {
//TODO
elementMap.erase(uid);
}
void ClientManager::UnloadAll() {
//TODO
elementMap.clear();
}
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) {
//TODO
std::map<int, ClientData>::iterator it = elementMap.find(uid);
if (it == elementMap.end()) {
return nullptr;
}
return &it->second;
}
int ClientManager::GetLoadedCount() {
//TODO
return elementMap.size();
}
int ClientManager::GetTotalCount() {
//TODO
return elementMap.size();
}
std::map<int, ClientData>* ClientManager::GetContainer() {
//TODO
return &elementMap;
}
+12 -5
View File
@@ -24,6 +24,7 @@
#include "client_data.hpp"
#include "manager_interface.hpp"
#include "server_packet.hpp"
#include "singleton.hpp"
#include "SDL/SDL_net.h"
@@ -31,16 +32,17 @@
#include <functional>
class ClientManager:
Singleton<ClientManager>,
ManagerInterface<ClientData, IPaddress>
public Singleton<ClientManager>,
public ManagerInterface<ClientData, IPaddress>
{
public:
//methods
int CheckConnections();
void HandlePong(ServerPacket* const argPacket);
//common public methods
int Create(IPaddress) override;
int Load(IPaddress) override;
int Save(int uid) override;
void Unload(int uid) override;
void Delete(int uid) override;
void UnloadAll() override;
void UnloadIf(std::function<bool(std::pair<const int, ClientData>)> fn) override;
@@ -57,6 +59,11 @@ private:
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;
};
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../server_utilities ../../common/utilities
INCLUDES+=. ../server_utilities ../../common/network ../../common/network/packet_types ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+2 -2
View File
@@ -31,8 +31,8 @@
#include <string>
class DoorManager:
Singleton<DoorManager>,
ManagerInterface<DoorData, std::string, Vector2>
public Singleton<DoorManager>,
public ManagerInterface<DoorData, std::string, Vector2>
{
public:
//common public methods
+2 -2
View File
@@ -38,8 +38,8 @@
#include <string>
class MonsterManager:
Singleton<MonsterManager>,
ManagerInterface<MonsterData, std::string>
public Singleton<MonsterManager>,
public ManagerInterface<MonsterData, std::string>
{
public:
//common public methods
-11
View File
@@ -22,16 +22,8 @@
#ifndef 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
#include "udp_network_utility.hpp"
#include "serial_packet.hpp"
#include "config_utility.hpp"
#include "singleton.hpp"
//APIs
@@ -67,8 +59,6 @@ private:
void HandlePacket(SerialPacket* const);
//basic connections
void HandlePing(ServerPacket* const);
void HandlePong(ServerPacket* const);
void HandleBroadcastRequest(ServerPacket* const);
void HandleJoinRequest(ClientPacket* const);
void HandleDisconnect(ClientPacket* const);
@@ -86,7 +76,6 @@ private:
void HandleSynchronize(ClientPacket* const);
//utility methods
void CheckClientConnections();
//TODO: a function that only sends to characters in a certain proximity
void CleanupLostConnection(int index);
void PumpPacket(SerialPacket* const);
+37 -19
View File
@@ -21,10 +21,21 @@
*/
#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
#include "sql_tools.hpp"
#include "utility.hpp"
//std & STL
#include <stdexcept>
#include <chrono>
#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.
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);
//-------------------------
@@ -58,7 +70,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
if (SDLNet_Init()) {
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;
//Init SQL
@@ -77,7 +89,7 @@ void ServerApplication::Init(int argc, char* argv[]) {
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) {
//get the original path
lua_getglobal(luaState, "package");
@@ -100,10 +112,10 @@ void ServerApplication::Init(int argc, char* argv[]) {
//-------------------------
//set the hooks
accountMgr.SetDatabase(database);
characterMgr.SetDatabase(database);
AccountManager::GetSingleton().SetDatabase(database);
CharacterManager::GetSingleton().SetDatabase(database);
roomMgr.SetLuaState(luaState);
RoomManager::GetSingleton().SetLuaState(luaState);
std::cout << "Internal managers initialized" << std::endl;
@@ -164,14 +176,17 @@ void ServerApplication::Proc() {
SerialPacket* packetBuffer = reinterpret_cast<SerialPacket*>(new char[MAX_PACKET_SIZE]);
while(running) {
//suck in the waiting packets & process them
while(network.Receive(packetBuffer)) {
while(UDPNetworkUtility::GetSingleton().Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
//update the internals
//...
//Check connections
CheckClientConnections();
int disconnected = ClientManager::GetSingleton().CheckConnections();
if (disconnected != -1) {
//TODO: clean up after this disconnection
}
//give the computer a break
SDL_Delay(10);
@@ -183,17 +198,15 @@ void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl;
//close the managers
clientMap.clear();
accountMgr.UnloadAll();
characterMgr.UnloadAll();
//TODO: unload combats
//TODO: unload enemies
roomMgr.UnloadAll();
ClientManager::GetSingleton().UnloadAll();
AccountManager::GetSingleton().UnloadAll();
CharacterManager::GetSingleton().UnloadAll();
RoomManager::GetSingleton().UnloadAll();
//APIs
lua_close(luaState);
sqlite3_close_v2(database);
network.Close();
UDPNetworkUtility::GetSingleton().Close();
SDLNet_Quit();
SDL_Quit();
@@ -206,13 +219,18 @@ void ServerApplication::Quit() {
void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
//basic connections
case SerialPacketType::PING:
HandlePing(static_cast<ServerPacket*>(argPacket));
//heartbeat system
case SerialPacketType::PING: {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
UDPNetworkUtility::GetSingleton().SendTo(argPacket->srcAddress, &newPacket);
}
break;
case SerialPacketType::PONG:
HandlePong(static_cast<ServerPacket*>(argPacket));
ClientManager::GetSingleton().HandlePong(static_cast<ServerPacket*>(argPacket));
break;
//connections
case SerialPacketType::BROADCAST_REQUEST:
HandleBroadcastRequest(static_cast<ServerPacket*>(argPacket));
break;
-38
View File
@@ -28,26 +28,6 @@
//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
void ServerApplication::HandleBroadcastRequest(ServerPacket* const argPacket) {
//send the server's data
@@ -293,24 +273,6 @@ void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//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
void ServerApplication::CleanupLostConnection(int clientIndex) {
//NOTE: This assumes each player has only one account and character at a time