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