Connection and disconnection are working correctly

I've dummied out the player code, so only the client connection code is
working. Otherwise the protocol hasn't changed.

I've also made a few other tweaks as I went along, but nothing really
major.
This commit is contained in:
Kayne Ruse
2014-03-04 02:46:19 +11:00
parent 7bb5e8ce0d
commit 756d4e770d
5 changed files with 99 additions and 95 deletions
+3
View File
@@ -94,6 +94,9 @@ union NetworkPacket {
Vector2 motion; Vector2 motion;
}playerInfo; }playerInfo;
//map data
//...
//defaults //defaults
NetworkPacket() { NetworkPacket() {
meta.type = Type::NONE; meta.type = Type::NONE;
+6
View File
@@ -38,6 +38,12 @@ int ClientManager::HandleDisconnection(int i) {
return -1; return -1;
} }
void ClientManager::ForEach(Lambda fn) {
for(Iterator it = clientMap.begin(); it != clientMap.end(); it++) {
fn(it);
}
}
ClientEntry* ClientManager::GetClient(int i) { ClientEntry* ClientManager::GetClient(int i) {
for (auto& it : clientMap) { for (auto& it : clientMap) {
if (it.first == i) { if (it.first == i) {
+11 -1
View File
@@ -24,6 +24,7 @@
#include "SDL/SDL_net.h" #include "SDL/SDL_net.h"
#include <functional>
#include <map> #include <map>
struct ClientEntry { struct ClientEntry {
@@ -32,15 +33,24 @@ struct ClientEntry {
class ClientManager { class ClientManager {
public: public:
//clarity typedefs
typedef std::map<int, ClientEntry> Container;
typedef Container::iterator Iterator;
typedef std::function<void(Iterator)> Lambda;
//returns the internal index //returns the internal index
int HandleConnection(IPaddress); int HandleConnection(IPaddress);
int HandleDisconnection(int i); int HandleDisconnection(int i);
//lambdas
void ForEach(Lambda);
//accessors //accessors
ClientEntry* GetClient(int i); ClientEntry* GetClient(int i);
ClientEntry* GetClient(IPaddress); ClientEntry* GetClient(IPaddress);
int Size() { return clientMap.size(); }
private: private:
std::map<int, ClientEntry> clientMap; Container clientMap;
int counter = 0; int counter = 0;
}; };
+65 -77
View File
@@ -30,21 +30,23 @@
using namespace std; using namespace std;
//------------------------- void runSQLScript(sqlite3* db, std::string fname) {
//Define the ServerApplication //Run setup scripts
//------------------------- ifstream is(fname);
if (!is.is_open()) {
ServerApplication::ServerApplication() { throw(runtime_error("Failed to run SQL script"));
// }
string script;
getline(is, script, '\0');
is.close();
sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr);
} }
ServerApplication::~ServerApplication() { //-------------------------
// //Define the public members
} //-------------------------
void ServerApplication::Init(int argc, char** argv) { void ServerApplication::Init(int argc, char** argv) {
//TODO: proper command line option parsing
//load config //load config
config.Load("rsc\\config.cfg"); config.Load("rsc\\config.cfg");
@@ -56,97 +58,85 @@ void ServerApplication::Init(int argc, char** argv) {
//Init SDL_net //Init SDL_net
if (SDLNet_Init()) { if (SDLNet_Init()) {
throw(runtime_error("Failed to init SDL_net")); throw(runtime_error("Failed to initialize SDL_net"));
} }
network.Open(config.Int("server.port"), sizeof(NetworkPacket)); network.Open(config.Int("server.port"), sizeof(NetworkPacket));
cout << "initialized SDL_net" << endl; cout << "initialized SDL_net" << endl;
//Init SQL //Init SQL
string dbname = (config["server.dbname"].size()) ? config["server.dbname"] : std::string(argv[0]) + ".db"; //fancy and unnecessary int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
int ret = sqlite3_open_v2(dbname.c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_FULLMUTEX, nullptr);
if (ret != SQLITE_OK || !database) { if (ret != SQLITE_OK || !database) {
throw(runtime_error("Failed to open the server database")); throw(runtime_error("Failed to open the server database"));
} }
cout << "initialized SQL" << endl; cout << "initialized SQL" << endl;
cout << "Database filename: " << dbname << endl;
//TODO: move this into a function? //setup the database
//Run setup scripts runSQLScript(database, config["dir.scripts"] + "setup_server.sql");
ifstream is("rsc\\scripts\\setup_server.sql"); cout << "initialized " << config["server.dbname"] << endl;
if (!is.is_open()) {
throw(runtime_error("Failed to run database setup script")); //lua
} //TODO
string script;
getline(is, script, '\0');
is.close();
sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr);
} }
void ServerApplication::Loop() { void ServerApplication::Loop() {
NetworkPacket packet; NetworkPacket packet;
while(running) { while(running) {
//suck in the waiting packets & process them //suck in the waiting packets & process them
try { while(network.Receive()) {
while(network.Receive()) { //get the packet
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); memcpy(&packet, network.GetInData(), sizeof(NetworkPacket));
packet.meta.srcAddress = network.GetInPacket()->address; //cache the source address
HandlePacket(packet); packet.meta.srcAddress = network.GetInPacket()->address;
} //we need to go deeper
HandlePacket(packet);
} }
catch(exception& e) {
cerr << "Network Error: " << e.what() << endl;
}
//give the computer a break //give the computer a break
SDL_Delay(10); SDL_Delay(10);
} }
} }
void ServerApplication::Quit() { void ServerApplication::Quit() {
//members //empty the members
network.Close(); //TODO: player manager
//TODO: client manager
//APIs //APIs
sqlite3_close_v2(database); sqlite3_close_v2(database);
network.Close();
SDLNet_Quit(); SDLNet_Quit();
SDL_Quit(); SDL_Quit();
} }
//-------------------------
//Define the uber switch
//-------------------------
void ServerApplication::HandlePacket(NetworkPacket packet) { void ServerApplication::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) { switch(packet.meta.type) {
case NetworkPacket::Type::BROADCAST_REQUEST: case NetworkPacket::Type::BROADCAST_REQUEST:
HandleBroadcastRequest(packet); HandleBroadcastRequest(packet);
break; break;
case NetworkPacket::Type::JOIN_REQUEST: case NetworkPacket::Type::JOIN_REQUEST:
HandleJoinRequest(packet); HandleJoinRequest(packet);
break; break;
case NetworkPacket::Type::DISCONNECT: case NetworkPacket::Type::DISCONNECT:
HandleDisconnect(packet); HandleDisconnect(packet);
break; break;
case NetworkPacket::Type::SYNCHRONIZE: case NetworkPacket::Type::SYNCHRONIZE:
HandleSynchronize(packet); // HandleSynchronize(packet);
break; break;
case NetworkPacket::Type::SHUTDOWN: case NetworkPacket::Type::SHUTDOWN:
HandleShutdown(packet); HandleShutdown(packet);
break; break;
case NetworkPacket::Type::PLAYER_NEW: case NetworkPacket::Type::PLAYER_NEW:
HandlePlayerNew(packet); // HandlePlayerNew(packet);
break; break;
case NetworkPacket::Type::PLAYER_DELETE: case NetworkPacket::Type::PLAYER_DELETE:
HandlePlayerDelete(packet); // HandlePlayerDelete(packet);
break; break;
case NetworkPacket::Type::PLAYER_UPDATE: case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet); // HandlePlayerUpdate(packet);
break; break;
//handle errors //handle errors
default: default:
throw(runtime_error("Unknown NetworkPacket::Type encountered")); throw(runtime_error("Unknown NetworkPacket::Type encountered"));
@@ -154,39 +144,38 @@ void ServerApplication::HandlePacket(NetworkPacket packet) {
} }
} }
//-------------------------
//Handle various network input
//-------------------------
void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) { void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) {
//send back the server's name //send back the server's name
packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE; packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE;
//TODO: version info
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
//TODO: player count
network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket)); network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket));
} }
void ServerApplication::HandleJoinRequest(NetworkPacket packet) { void ServerApplication::HandleJoinRequest(NetworkPacket packet) {
//TODO: prevent duplicate logins from the same address? //register the new client
int index = clientMgr.HandleConnection(packet.meta.srcAddress);
//create the new client, filling it with the correct info
Client newClient;
newClient.address = packet.meta.srcAddress;
//push the new client
clientMap[clientCounter] = newClient;
//send the client their info //send the client their info
packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE;
packet.clientInfo.index = clientCounter; packet.clientInfo.index = index;
network.Send(&newClient.address, &packet, sizeof(NetworkPacket)); network.Send(&clientMgr.GetClient(index)->address, &packet, sizeof(NetworkPacket));
//finished this routine //finished this routine
clientCounter++; cout << "connect, total: " << clientMgr.Size() << endl;
cout << "connect, total: " << clientMap.size() << endl;
} }
void ServerApplication::HandleDisconnect(NetworkPacket packet) { void ServerApplication::HandleDisconnect(NetworkPacket packet) {
//disconnect the specified client //disconnect the specified client
network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); network.Send(&clientMgr.GetClient(packet.clientInfo.index)->address, &packet, sizeof(NetworkPacket));
clientMap.erase(packet.clientInfo.index); clientMgr.HandleDisconnection(packet.clientInfo.index);
//delete players /* //delete players
erase_if(playerMap, [&](pair<int, Player> it) -> bool { erase_if(playerMap, [&](pair<int, Player> it) -> bool {
if (it.second.clientIndex == packet.clientInfo.index) { if (it.second.clientIndex == packet.clientInfo.index) {
NetworkPacket delPacket; NetworkPacket delPacket;
@@ -202,10 +191,12 @@ void ServerApplication::HandleDisconnect(NetworkPacket packet) {
} }
return false; return false;
}); });
*/
cout << "disconnect, total: " << clientMap.size() << endl; //finished this routine
cout << "disconnect, total: " << clientMgr.Size() << endl;
} }
/*
void ServerApplication::HandleSynchronize(NetworkPacket packet) { void ServerApplication::HandleSynchronize(NetworkPacket packet) {
//send all the server's data to this client //send all the server's data to this client
NetworkPacket newPacket; NetworkPacket newPacket;
@@ -221,18 +212,21 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) {
network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket)); network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket));
} }
} }
*/
void ServerApplication::HandleShutdown(NetworkPacket packet) { void ServerApplication::HandleShutdown(NetworkPacket packet) {
//end the server //end the server
running = false; running = false;
//disconnect all clients //disconnect all clients
packet.meta.type = NetworkPacket::Type::DISCONNECT; packet.meta.type = NetworkPacket::Type::DISCONNECT;
PumpPacket(packet); clientMgr.ForEach([&](ClientManager::Iterator it) -> void {
this->network.Send(&it->second.address, &packet, sizeof(NetworkPacket));
});
//finished this routine
cout << "shutting down" << endl; cout << "shutting down" << endl;
} }
/*
void ServerApplication::HandlePlayerNew(NetworkPacket packet) { void ServerApplication::HandlePlayerNew(NetworkPacket packet) {
//create the new player object //create the new player object
Player newPlayer; Player newPlayer;
@@ -291,10 +285,4 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) {
PumpPacket(packet); PumpPacket(packet);
} }
*/
void ServerApplication::PumpPacket(NetworkPacket packet) {
//send this packet to all clients
for (auto& it : clientMap) {
network.Send(&it.second.address, &packet, sizeof(NetworkPacket));
}
}
+14 -17
View File
@@ -31,12 +31,13 @@
#include "SDL/SDL.h" #include "SDL/SDL.h"
//misc //misc
#include "client_manager.hpp"
#include "player_manager.hpp"
//common
#include "config_utility.hpp" #include "config_utility.hpp"
#include "vector2.hpp" #include "vector2.hpp"
#include "client.hpp"
#include "player.hpp"
//STL //STL
#include <map> #include <map>
#include <string> #include <string>
@@ -45,8 +46,8 @@
class ServerApplication { class ServerApplication {
public: public:
//standard functions //standard functions
ServerApplication(); ServerApplication() = default;
~ServerApplication(); ~ServerApplication() = default;
void Init(int argc, char** argv); void Init(int argc, char** argv);
void Loop(); void Loop();
@@ -59,13 +60,11 @@ private:
void HandleBroadcastRequest(NetworkPacket); void HandleBroadcastRequest(NetworkPacket);
void HandleJoinRequest(NetworkPacket); void HandleJoinRequest(NetworkPacket);
void HandleDisconnect(NetworkPacket); void HandleDisconnect(NetworkPacket);
void HandleSynchronize(NetworkPacket); // void HandleSynchronize(NetworkPacket);
void HandleShutdown(NetworkPacket); void HandleShutdown(NetworkPacket);
void HandlePlayerNew(NetworkPacket); // void HandlePlayerNew(NetworkPacket);
void HandlePlayerDelete(NetworkPacket); // void HandlePlayerDelete(NetworkPacket);
void HandlePlayerUpdate(NetworkPacket); // void HandlePlayerUpdate(NetworkPacket);
void PumpPacket(NetworkPacket);
//networking //networking
UDPNetworkUtility network; UDPNetworkUtility network;
@@ -73,16 +72,14 @@ private:
//database //database
sqlite3* database = nullptr; sqlite3* database = nullptr;
//lua
//TODO
//misc //misc
bool running = true; bool running = true;
ConfigUtility config; ConfigUtility config;
//global lists ClientManager clientMgr;
ClientMap clientMap;
PlayerMap playerMap;
int clientCounter = 0;
int playerCounter = 0;
}; };
#endif #endif