diff --git a/server/server_application.cpp b/server/server_application.cpp index f940edc..d9d6d4b 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -36,30 +36,6 @@ using namespace std; int ClientInformation::counter = 0; -//------------------------- -//Define the network thread -//------------------------- - -/* This thread sucks in the packets sent to the server, and pushes them onto the queue. - * This function is declared as a friend of ServerApplication, because I'm lazy -*/ -int networkQueueThread(void* ptr) { - ServerApplication* app = reinterpret_cast(ptr); - NetworkPacket packet; - - while(app->running) { - //suck in the waiting packets - while(app->networkUtil.Receive()) { - memcpy(&packet, app->networkUtil.GetInData(), sizeof(NetworkPacket)); - //this is important: keep track of the source address - packet.meta.srcAddress = app->networkUtil.GetInPacket()->address; - app->networkQueue.PushBack(packet); - } - SDL_Delay(10); - } - return 0; -} - //------------------------- //Define the ServerApplication //------------------------- @@ -75,12 +51,6 @@ ServerApplication::~ServerApplication() { void ServerApplication::Init(int argc, char** argv) { //TODO: proper command line option parsing - //Check prerequisites - if (!sqlite3_threadsafe()) { - throw(runtime_error("Cannot run without thread safety")); - } - cout << "Thread safety confirmed" << endl; - //load config config.Load("rsc\\config.cfg"); @@ -94,7 +64,7 @@ void ServerApplication::Init(int argc, char** argv) { if (SDLNet_Init()) { throw(runtime_error("Failed to init SDL_net")); } - networkUtil.Open(config.Int("server.port"), sizeof(NetworkPacket)); + network.Open(config.Int("server.port"), sizeof(NetworkPacket)); cout << "initialized SDL_net" << endl; //Init SQL @@ -116,26 +86,25 @@ void ServerApplication::Init(int argc, char** argv) { getline(is, script, '\0'); is.close(); sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr); - - //setup the threads - networkQueueThread = SDL_CreateThread(&::networkQueueThread, this); - if (!networkQueueThread) { - throw(runtime_error("Failed to create the networkQueueThread")); - } - cout << "initialized networkQueueThread" << endl; } void ServerApplication::Loop() { //debugging + + NetworkPacket packet; + while(running) { - while(networkQueue.Size() > 0) { - try { - HandlePacket(networkQueue.PopFront()); + //suck in the waiting packets & process them + try { + while(network.Receive()) { + memcpy(&packet, network.GetInData(), sizeof(NetworkPacket)); + packet.meta.srcAddress = network.GetInPacket()->address; + HandlePacket(packet); } - catch(exception& e) { - cerr << "Network Error: " << e.what() << endl; - } - }; + } + catch(exception& e) { + cerr << "Network Error: " << e.what() << endl; + } //give the computer a break SDL_Delay(10); @@ -143,12 +112,8 @@ void ServerApplication::Loop() { } void ServerApplication::Quit() { - //catch all signal - running = false; - //members - SDL_WaitThread(networkQueueThread, nullptr); - networkUtil.Close(); + network.Close(); //APIs sqlite3_close_v2(database); @@ -162,7 +127,7 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { //send back the server's name packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE; snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str()); - networkUtil.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket)); + network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket)); break; case NetworkPacket::Type::JOIN_REQUEST: { //TODO: prevent duplicate logins from the same address? @@ -178,14 +143,14 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { //send the client their info packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE; packet.clientInfo.index = newClient.index; - networkUtil.Send(&newClient.address, &packet, sizeof(NetworkPacket)); + network.Send(&newClient.address, &packet, sizeof(NetworkPacket)); cout << "connect, total: " << clientInfo.size() << endl; } break; case NetworkPacket::Type::DISCONNECT: //disconnect the specified client - networkUtil.Send(&clientInfo[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); + network.Send(&clientInfo[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket)); clientInfo.erase(packet.clientInfo.index); cout << "disconnect, total: " << clientInfo.size() << endl; @@ -200,7 +165,7 @@ void ServerApplication::HandlePacket(NetworkPacket packet) { //disconnect all clients packet.meta.type = NetworkPacket::Type::DISCONNECT; for (auto& it : clientInfo) { - networkUtil.Send(&it.second.address, &packet, sizeof(NetworkPacket)); + network.Send(&it.second.address, &packet, sizeof(NetworkPacket)); } cout << "shutting down" << endl; diff --git a/server/server_application.hpp b/server/server_application.hpp index e579fe5..a2d1432 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -24,19 +24,18 @@ //networking #include "network_packet.hpp" -#include "thread_safe_queue.hpp" #include "udp_network_utility.hpp" //APIs #include "sqlite3/sqlite3.h" #include "SDL/SDL.h" -#include "SDL/SDL_thread.h" //misc #include "config_utility.hpp" -#include "world_room.hpp" +//STL #include +#include //hold the client info struct ClientInformation { @@ -56,14 +55,12 @@ public: void Loop(); void Quit(); - friend int networkQueueThread(void*); private: void HandlePacket(NetworkPacket); //networking - UDPNetworkUtility networkUtil; - ThreadSafeQueue networkQueue; - SDL_Thread* networkQueueThread = nullptr; + UDPNetworkUtility network; + std::queue networkQueue; //database sqlite3* database = nullptr; @@ -71,7 +68,6 @@ private: //misc bool running = true; ConfigUtility config; - WorldRoom worldRoom; std::map clientInfo; }; diff --git a/server/thread_safe_queue.hpp b/server/thread_safe_queue.hpp deleted file mode 100644 index 128d555..0000000 --- a/server/thread_safe_queue.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef THREADSAFEQUEUE_HPP_ -#define THREADSAFEQUEUE_HPP_ - -#include "SDL/SDL_thread.h" - -#include -#include - -/* This container is a thread safe reimplementation of std::queue. -*/ - -template> -class ThreadSafeQueue { -public: - ThreadSafeQueue() { - lock = SDL_CreateSemaphore(1); - if (!lock) { - throw(std::runtime_error("Failed to create ThreadSafeQueue::lock")); - } - } - - ~ThreadSafeQueue() { - SDL_DestroySemaphore(lock); - } - - T PushBack(T t) { - SDL_SemWait(lock); - container.push_back(t); - SDL_SemPost(lock); - return t; - } - - T PeekFront() { - T t; - SDL_SemWait(lock); - if (container.size() > 0) { - t = container[0]; - } - SDL_SemPost(lock); - return t; - } - - T PopFront() { - T t; - SDL_SemWait(lock); - if (container.size() > 0) { - t = container[0]; - container.pop_front(); - } - SDL_SemPost(lock); - return t; - } - - int Size() { - //can't be sure if std::deque::size() is thread safe - int ret; - SDL_SemWait(lock); - ret = container.size(); - SDL_SemPost(lock); - return ret; - } - -private: - Container container; - SDL_sem* lock; -}; - -#endif diff --git a/server/world_room.cpp b/server/world_room.cpp deleted file mode 100644 index 91e02bc..0000000 --- a/server/world_room.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#include "world_room.hpp" - -#include -#include - -using namespace std; - -//------------------------- -//Define the WorldRoom's thread -//------------------------- - -int worldRoomThread(void* ptr) { - WorldRoom* room = reinterpret_cast(ptr); - try { - room->Init(); - room->Loop(); - room->Quit(); - } - catch(std::exception& e) { - cerr << "Fatal Room Error: " << e.what() << endl; - return 1; - } - return 0; -} - -//------------------------- -//Define the WorldRoom's methods -//------------------------- - -WorldRoom::WorldRoom() { - // -} - -WorldRoom::~WorldRoom() { - // -} - -void WorldRoom::Init() { - // -} - -void WorldRoom::Loop() { - // -} - -void WorldRoom::Quit() { - // -} - -void WorldRoom::HandlePacket(NetworkPacket packet) { - switch(packet.meta.type) { - -// case NetworkPacket::Type::SYNCHRONIZE: -// // -// break; - - //handle errors - default: - throw(runtime_error("Unknown NetworkPacket::Type encountered")); - break; - } -} diff --git a/server/world_room.hpp b/server/world_room.hpp deleted file mode 100644 index 0a3fc0f..0000000 --- a/server/world_room.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#ifndef WORLDROOM_HPP_ -#define WORLDROOM_HPP_ - -#include "network_packet.hpp" -#include "thread_safe_queue.hpp" - -class WorldRoom { -public: - WorldRoom(); - ~WorldRoom(); - - void Init(); - void Loop(); - void Quit(); - - ThreadSafeQueue* GetNetworkQueue() { return &networkQueue; } -private: - void HandlePacket(NetworkPacket); - - ThreadSafeQueue networkQueue; -}; - -#endif