diff --git a/server/client_manager.hpp b/common/network_packet.hpp similarity index 62% rename from server/client_manager.hpp rename to common/network_packet.hpp index a84b8bb..a78934f 100644 --- a/server/client_manager.hpp +++ b/common/network_packet.hpp @@ -19,26 +19,42 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef CLIENTMANAGER_HPP_ -#define CLIENTMANAGER_HPP_ +#ifndef NETWORKPACKET_HPP_ +#define NETWORKPACKET_HPP_ -#include +//#define PACKET_STRING_SIZE 100 -class ClientManager { -private: - ClientManager() = default; - ~ClientManager() = default; - static ClientManager instance; +#pragma pack(push, 0) -public: - static ClientManager* GetInstance() { return &instance; } +union NetworkPacket { + enum class Type { + //default: there is something wrong + NONE = 0, -private: - struct ClientEntry { - int index; + //not used + PING = 1, + PONG = 2, + + //bounce information between the client & server + BROADCAST_REQUEST = 3, + BROADCAST_RESPONSE = 4, + + //try to join the server + JOIN_REQUEST = 5, + JOIN_RESPONSE = 6, + + //disconnect from the server + DISCONNECT = 7, + + //mass update + SYNCHRONIZE = 8, }; - std::list list; + struct Metadata { + Type type; + }meta; }; +#pragma pack(pop) + #endif diff --git a/common/udp_network_utility.cpp b/common/udp_network_utility.cpp new file mode 100644 index 0000000..5f828c7 --- /dev/null +++ b/common/udp_network_utility.cpp @@ -0,0 +1,148 @@ +/* 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 "udp_network_utility.hpp" + +#include + +void UDPNetworkUtility::Open(int port, int packSize) { + if (!(socket = SDLNet_UDP_Open(port))) { + Close(); + throw(std::runtime_error("Failed to open a UDP socket")); + } + + if (!(packOut = SDLNet_AllocPacket(packSize))) { + Close(); + throw(std::runtime_error("Failed to allocate the out packet")); + } + + if (!(packIn = SDLNet_AllocPacket(packSize))) { + Close(); + throw(std::runtime_error("Failed to allocate the in packet")); + } +} + +void UDPNetworkUtility::Close() { + SDLNet_UDP_Close(socket); + SDLNet_FreePacket(packOut); + SDLNet_FreePacket(packIn); + socket = nullptr; + packOut = nullptr; + packIn = nullptr; +} + +int UDPNetworkUtility::Bind(const char* ip, int port, int channel) { + IPaddress add; + if (SDLNet_ResolveHost(&add, ip, port) == -1) { + throw(std::runtime_error("Failed to resolve a host")); + } + + return Bind(&add, channel); +} + +int UDPNetworkUtility::Bind(IPaddress* add, int channel) { + int ret = SDLNet_UDP_Bind(socket, channel, add); + + if (ret == -1) { + throw(std::runtime_error("Failed to bind to a channel")); + } + + return ret; +} + +void UDPNetworkUtility::Unbind(int channel) { + SDLNet_UDP_Unbind(socket, channel); +} + +int UDPNetworkUtility::Send(const char* ip, int port, void* data, int len) { + IPaddress add; + if (SDLNet_ResolveHost(&add, ip, port) == -1) { + throw(std::runtime_error("Failed to resolve a host")); + } + + Send(&add, data, len); +} + +int UDPNetworkUtility::Send(IPaddress* add, void* data, int len) { + if (len > packOut->maxlen) { + throw(std::runtime_error("Failed to copy the data into the packet")); + } + memset(packOut->data, 0, packOut->maxlen); + memcpy(packOut->data, data, len); + packOut->len = len; + packOut->address = *add; + + int ret = SDLNet_UDP_Send(socket, -1, packOut); + + if (ret <= 0) { + throw(std::runtime_error("Failed to send a packet")); + } + + return ret; +} + +int UDPNetworkUtility::Send(int channel, void* data, int len) { + if (len > packOut->maxlen) { + throw(std::runtime_error("Failed to copy the data into the packet")); + } + memset(packOut->data, 0, packOut->maxlen); + memcpy(packOut->data, data, len); + packOut->len = len; + + int ret = SDLNet_UDP_Send(socket, channel, packOut); + + if (ret <= 0) { + throw(std::runtime_error("Failed to send a packet")); + } + + return ret; +} + +int UDPNetworkUtility::SendAll(void* data, int len) { + if (len > packOut->maxlen) { + throw(std::runtime_error("Failed to copy the data into the packet")); + } + memset(packOut->data, 0, packOut->maxlen); + memcpy(packOut->data, data, len); + packOut->len = len; + + int sent = 0; + + //send to all bound channels + for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) { + if (SDLNet_UDP_GetPeerAddress(socket, i)) { + sent += SDLNet_UDP_Send(socket, i, packOut); + } + } + + return sent; +} + +int UDPNetworkUtility::Receive() { + memset(packIn->data, 0, packIn->maxlen); + int ret = SDLNet_UDP_Recv(socket, packIn); + + if (ret < 0) { + throw(std::runtime_error("Unknown network error occured")); + } + + return ret; +} diff --git a/common/udp_network_utility.hpp b/common/udp_network_utility.hpp new file mode 100644 index 0000000..9ba7842 --- /dev/null +++ b/common/udp_network_utility.hpp @@ -0,0 +1,71 @@ +/* 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 UDPNETWORKUTILITY_HPP_ +#define UDPNETWORKUTILITY_HPP_ + +#include "SDL/SDL_net.h" + +class UDPNetworkUtility { +public: + UDPNetworkUtility() = default; + ~UDPNetworkUtility() = default; + + void Open(int port, int packSize); + void Close(); + + //bind to a channel + int Bind(const char* ip, int port, int channel = -1); + int Bind(IPaddress* add, int channel = -1); + void Unbind(int channel); + + IPaddress* GetIPAddress(int channel) { + return SDLNet_UDP_GetPeerAddress(socket, channel); + } + + int Send(const char* ip, int port, void* data, int len); + int Send(IPaddress* add, void* data, int len); + int Send(int channel, void* data, int len); + int SendAll(void* data, int len); + int Receive(); + + void* GetOutData() const { + return reinterpret_cast(packOut->data); + }; + void* GetInData() const { + return reinterpret_cast(packIn->data); + }; + UDPpacket* GetOutPacket() const { + return packOut; + } + UDPpacket* GetInPacket() const { + return packIn; + } + UDPsocket GetSocket() const { + return socket; + } +private: + UDPsocket socket = nullptr; + UDPpacket* packOut = nullptr; + UDPpacket* packIn = nullptr; +}; + +#endif diff --git a/server/client_manager.cpp b/server/client_manager.cpp deleted file mode 100644 index 991e40a..0000000 --- a/server/client_manager.cpp +++ /dev/null @@ -1,25 +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 "client_manager.hpp" - -ClientManager ClientManager::instance; - diff --git a/server/makefile b/server/makefile index 515e82f..840f805 100644 --- a/server/makefile +++ b/server/makefile @@ -1,7 +1,7 @@ #config COMMONDIR+=../common COMMON+=../libcommon.a -LIB+=$(COMMON) -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 +LIB+=$(COMMON) -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(COMMONDIR)) CFLAGS+=-DDEBUG $(addprefix -I,$(COMMONDIR)) diff --git a/server/server_application.cpp b/server/server_application.cpp index addcc0a..e4c9a64 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -21,11 +21,14 @@ */ #include "server_application.hpp" +#include "network_packet.hpp" + #include #include #include #include +int ClientEntry::indexCounter = 0; ServerApplication ServerApplication::instance; ServerApplication::ServerApplication() { @@ -37,6 +40,8 @@ ServerApplication::~ServerApplication() { } void ServerApplication::Init(int argc, char** argv) { + //TODO: proper command line option parsing + //Check thread safety if (!sqlite3_threadsafe()) { throw(std::runtime_error("Cannot run without thread safety")); @@ -53,14 +58,14 @@ void ServerApplication::Init(int argc, char** argv) { std::cout << "SDL initialized" << std::endl; } - //Init lua - if (!(luaState = luaL_newstate())) { - throw(std::runtime_error("Failed to create the lua state")); + //Init SDL_net + if (SDLNet_Init()) { + throw(std::runtime_error("Failed to init SDL_net")); } else { - std::cout << "lua initialized" << std::endl; + std::cout << "SDL_net initialized" << std::endl; } - luaL_openlibs(luaState); + networkUtil.Open(8895, 1024); //Init SQL std::string dbname = (argc > 1) ? argv[1] : argv[0]; @@ -73,8 +78,6 @@ void ServerApplication::Init(int argc, char** argv) { } //Run setup scripts - luaL_dofile(luaState, "rsc/setup_server.lua"); - std::ifstream is("rsc/setup_server.sql"); if (!is.is_open()) { throw(std::runtime_error("Failed to run database setup script")); @@ -90,11 +93,12 @@ void ServerApplication::Init(int argc, char** argv) { } void ServerApplication::Loop() { - //TODO + // } void ServerApplication::Quit() { sqlite3_close_v2(database); - lua_close(luaState); + networkUtil.Close(); + SDLNet_Quit(); SDL_Quit(); } diff --git a/server/server_application.hpp b/server/server_application.hpp index d58cbc8..d89811f 100644 --- a/server/server_application.hpp +++ b/server/server_application.hpp @@ -22,10 +22,20 @@ #ifndef SERVERAPPLICATION_HPP_ #define SERVERAPPLICATION_HPP_ -#include "lua/lua.hpp" +#include "udp_network_utility.hpp" + #include "sqlite3/sqlite3.h" #include "SDL/SDL.h" +#include + +//hold the info about the clients +struct ClientEntry { + static int indexCounter; + int index = indexCounter++; + IPaddress add = {0, 0}; +}; + //The main application class class ServerApplication { private: @@ -43,8 +53,10 @@ public: private: bool running = true; - lua_State* luaState = nullptr; sqlite3* database = nullptr; + + UDPNetworkUtility networkUtil; + std::list clientEntries; }; #endif