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:
@@ -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;
|
||||
}
|
||||
@@ -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,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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user