Smooth connection and disconnection complete

The clients can connect and disconnect from the server with known no
issues. There is no way to shutdown the server yet, but it might be
possible to kick someone else from the server soon.
This commit is contained in:
Kayne Ruse
2013-06-18 16:21:42 +10:00
parent e833129983
commit 33474cc6c0
14 changed files with 177 additions and 41 deletions
+85 -2
View File
@@ -12,6 +12,7 @@ InWorld::InWorld() {
#ifdef DEBUG
cout << "entering InWorld" << endl;
#endif
cout << "Client Index: " << infoMgr->GetClientIndex() << endl;
}
InWorld::~InWorld() {
@@ -29,7 +30,7 @@ void InWorld::FrameStart() {
}
void InWorld::Update(double delta) {
//
while(HandlePacket(popNetworkPacket()));
}
void InWorld::FrameEnd() {
@@ -44,6 +45,12 @@ void InWorld::Render(SDL_Surface* const screen) {
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//ensure that the client is disconnected properly
ExitGame();
SetNextScene(SceneList::QUIT);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
@@ -59,7 +66,7 @@ void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
ExitGame();
break;
}
}
@@ -67,3 +74,79 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Utilities
//-------------------------
int InWorld::HandlePacket(Packet p) {
switch(p.meta.type) {
case PacketType::NONE:
//DO NOTHING
return 0;
break;
case PacketType::PING:
//quick pong
p.meta.type = PacketType::PONG;
netUtil->Send(&p.meta.address, &p, sizeof(Packet));
break;
case PacketType::PONG:
//
break;
// case PacketType::BROADCAST_REQUEST:
// //
// break;
// case PacketType::BROADCAST_RESPONSE:
// //
// break;
// case PacketType::JOIN_REQUEST:
// //
// break;
// case PacketType::JOIN_RESPONSE:
// //
// break;
case PacketType::DISCONNECT:
HandleDisconnection(p.disconnect);
break;
// case PacketType::SYNCHRONIZE:
// //
// break;
// case PacketType::PLAYER_NEW:
// //
// break;
// case PacketType::PLAYER_DELETE:
// //
// break;
// case PacketType::PLAYER_MOVE:
// //
// break;
default:
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
void InWorld::Disconnect() {
//disconnect
Packet p;
p.meta.type = PacketType::DISCONNECT;
p.disconnect.clientIndex = infoMgr->GetClientIndex();
netUtil->Send(GAME_CHANNEL, reinterpret_cast<void*>(&p), sizeof(Packet));
netUtil->Unbind(GAME_CHANNEL);
endQueueThread();
//reset the client
infoMgr->ResetClientIndex();
}
void InWorld::ExitGame() {
Disconnect();
SetNextScene(SceneList::MAINMENU);
cout << "The game session has ended" << endl;
}
void InWorld::HandleDisconnection(::Disconnect& disconnect) {
Disconnect();
SetNextScene(SceneList::MAINMENU);
cout << "You have been disconnected" << endl;
}
+30 -3
View File
@@ -2,26 +2,53 @@
#define INWORLD_HPP_
#include "base_scene.hpp"
#include "defines.hpp"
#include "service_locator.hpp"
#include "packet_type.hpp"
#include "network_queue.hpp"
#include "information_manager.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
#include "udp_network_utility.hpp"
#include "button.hpp"
#include "raster_font.hpp"
class InWorld : public BaseScene {
public:
/* Public access members */
//Public access members
InWorld();
~InWorld();
protected:
/* Frame loop */
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
/* Event handlers */
//Event handlers
void QuitEvent();
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//Utilities
int HandlePacket(Packet p);
void Disconnect();
void ExitGame();
void HandleDisconnection(::Disconnect&);
//services
ConfigUtility* configUtil = ServiceLocator<ConfigUtility>::Get();
SurfaceManager* surfaceMgr = ServiceLocator<SurfaceManager>::Get();
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
InformationManager* infoMgr = ServiceLocator<InformationManager>::Get();
//members
//...
};
#endif
+1
View File
@@ -5,6 +5,7 @@ class InformationManager {
public:
int SetClientIndex(int i) { return clientIndex = i; }
int GetClientIndex() { return clientIndex; }
void ResetClientIndex() { clientIndex = -1; }
private:
int clientIndex = -1;
};
+5 -10
View File
@@ -26,12 +26,12 @@ Lobby::Lobby() {
serverList.push_back({"bar",{0,0}});
serverList.push_back({"foobar",{0,0}});
BeginQueueThread();
flushNetworkQueue();
beginQueueThread();
BroadcastNetwork();
}
Lobby::~Lobby() {
EndQueueThread();
#ifdef DEBUG
cout << "leaving Lobby" << endl;
#endif
@@ -46,13 +46,7 @@ void Lobby::FrameStart() {
}
void Lobby::Update(double delta) {
try {
//process all packets on the network queue
while(HandlePacket(popNetworkPacket()));
}
catch(exception& e) {
cerr << "Network Error: " << e.what() << endl;
}
while(HandlePacket(popNetworkPacket()));
}
void Lobby::FrameEnd() {
@@ -102,6 +96,7 @@ void Lobby::MouseButtonUp(SDL_MouseButtonEvent const& button) {
}
else if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
endQueueThread();
}
else if (
//clicked within bounds TODO: make the damn collision system
@@ -178,7 +173,7 @@ int Lobby::HandlePacket(Packet p) {
// //
// break;
default:
throw(runtime_error("Failed to recognize the packet type"));
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
+1 -3
View File
@@ -1,8 +1,8 @@
#ifndef LOBBY_HPP_
#define LOBBY_HPP_
#include "defines.hpp"
#include "base_scene.hpp"
#include "defines.hpp"
#include "service_locator.hpp"
#include "packet_type.hpp"
#include "network_queue.hpp"
@@ -14,8 +14,6 @@
#include "button.hpp"
#include "raster_font.hpp"
#include "SDL/SDL_thread.h"
#include <vector>
#include <string>
+1 -1
View File
@@ -2,8 +2,8 @@
#define SPLASHSCREEN_HPP_
#include "base_scene.hpp"
#include "service_locator.hpp"
#include "defines.hpp"
#include "service_locator.hpp"
#include "config_utility.hpp"
#include "surface_manager.hpp"
+9
View File
@@ -0,0 +1,9 @@
#include "defines.hpp"
#include <cstdio>
std::string itos(int i) {
char buffer[20];
snprintf(buffer, 20, "%d", i);
return std::string(buffer);
}
+3
View File
@@ -2,10 +2,13 @@
#define DEFINES_HPP
#include <chrono>
#include <string>
#define GAME_CHANNEL 0
#define CHAT_CHANNEL 1
typedef std::chrono::high_resolution_clock Clock;
std::string itos(int i);
#endif
+11 -3
View File
@@ -31,7 +31,7 @@ static int networkQueue(void*) {
return 0;
}
void BeginQueueThread() {
void beginQueueThread() {
if (running) {
return;
}
@@ -41,7 +41,7 @@ void BeginQueueThread() {
}
}
void EndQueueThread() {
void endQueueThread() {
if (!running) {
return;
}
@@ -50,7 +50,7 @@ void EndQueueThread() {
queueThread = nullptr;
}
void KillQueueThread() {
void killQueueThread() {
if (!running) {
return;
}
@@ -78,4 +78,12 @@ Packet popNetworkPacket() {
}
SDL_SemPost(lock);
return p;
}
void flushNetworkQueue() {
UDPNetworkUtility* netUtil = ServiceLocator<UDPNetworkUtility>::Get();
SDL_SemWait(lock);
while(netUtil->Receive());
queue.clear();
SDL_SemPost(lock);
}
+4 -3
View File
@@ -3,10 +3,11 @@
#include "packet_type.hpp"
void BeginQueueThread();
void EndQueueThread();
void KillQueueThread();
void beginQueueThread();
void endQueueThread();
void killQueueThread();
Packet peekNetworkPacket();
Packet popNetworkPacket();
void flushNetworkQueue();
#endif
+1
View File
@@ -62,6 +62,7 @@ struct JoinResponse {
struct Disconnect {
Metadata meta;
int clientIndex;
};
struct Synchronize {
+22 -9
View File
@@ -56,7 +56,7 @@ void ServerApplication::Init() {
netUtil->Open(configUtil->Int("server.port"), sizeof(Packet));
//create the threads
BeginQueueThread();
beginQueueThread();
//output the server information
cout << configUtil->String("server.name") << endl;
@@ -84,7 +84,7 @@ void ServerApplication::Proc() {
void ServerApplication::Quit() {
//close the threads
EndQueueThread();
endQueueThread();
//clean up the services
netUtil->Close();
@@ -126,7 +126,7 @@ int ServerApplication::HandlePacket(Packet p) {
//
break;
case PacketType::BROADCAST_REQUEST:
Broadcast(p.broadcastRequest);
HandleBroadcast(p.broadcastRequest);
break;
// case PacketType::BROADCAST_RESPONSE:
// //
@@ -137,9 +137,9 @@ int ServerApplication::HandlePacket(Packet p) {
// case PacketType::JOIN_RESPONSE:
// //
// break;
// case PacketType::DISCONNECT:
// //
// break;
case PacketType::DISCONNECT:
HandleDisconnection(p.disconnect);
break;
// case PacketType::SYNCHRONIZE:
// //
// break;
@@ -153,12 +153,12 @@ int ServerApplication::HandlePacket(Packet p) {
// //
// break;
default:
throw(runtime_error("Failed to recognize the packet type"));
throw(runtime_error("Failed to recognize the packet type: " + itos(int(p.meta.type))));
}
return 1;
}
void ServerApplication::Broadcast(BroadcastRequest& bcast) {
void ServerApplication::HandleBroadcast(BroadcastRequest& bcast) {
//respond to a broadcast request with the server's data
Packet p;
p.meta.type = PacketType::BROADCAST_RESPONSE;
@@ -189,6 +189,19 @@ void ServerApplication::HandleConnection(JoinRequest& request) {
netUtil->Send(client.channel, &p, sizeof(Packet));
//pretty
cout << "New connection" << endl;
cout << "New connection: index " << client.index << endl;
cout << "number of clients: " << clients.size() << endl;
}
void ServerApplication::HandleDisconnection(Disconnect& disconnect) {
//disconnect a client (redundant message)
netUtil->Send(clients[disconnect.clientIndex].channel, &disconnect, sizeof(Packet));
netUtil->Unbind(clients[disconnect.clientIndex].channel);
clients.erase(disconnect.clientIndex);
//remove the player...
//pretty
cout << "Lost connection: index " << disconnect.clientIndex << endl;
cout << "number of clients: " << clients.size() << endl;
}
+2 -1
View File
@@ -50,8 +50,9 @@ private:
//network loop
int HandlePacket(Packet p);
void Broadcast(BroadcastRequest&);
void HandleBroadcast(BroadcastRequest&);
void HandleConnection(JoinRequest&);
void HandleDisconnection(Disconnect&);
//services
ConfigUtility* configUtil = nullptr;
+2 -6
View File
@@ -1,11 +1,7 @@
#include "packet_type.hpp"
#include "defines.hpp"
#include <iostream>
using namespace std;
int main(int, char**) {
Packet p;
cout << int(p.meta.type) << endl;
std::string s = itos(5);
return 0;
}